home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / basic / qbscr15.zip / QBSCR.DOC < prev    next >
Text File  |  1989-09-05  |  213KB  |  5,509 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.                                    Q B S C R
  9.  
  10.                          S C R E E N   R O U T I N E S
  11.  
  12.  
  13.  
  14.                                     for the
  15.  
  16.                           QuickBASIC 4.0+ Programmer
  17.  
  18.  
  19.                              V e r s i o n   1 . 5
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.                            Conceived and Created by
  31.  
  32.                                   Tony Martin
  33.  
  34.                                       of
  35.  
  36.                            The BAD SOFTWARE Company
  37.                             1611 Harvest Green Ct.
  38.                                Reston, VA 22094
  39.  
  40.                                September 1 1989
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.                Software and Documentation (C) Copyright 1989 by
  51.                                   Tony Martin
  52.  
  53.  
  54.  
  55.  
  56.  
  57.          T A B L E   O F   C O N T E N T S
  58.          -------------------------------------------------------------
  59.  
  60.  
  61.                    Welcome to the QBSCR Screen Routines . . . . . .  1
  62.  
  63.                    A Few Notices  . . . . . . . . . . . . . . . . .  2
  64.  
  65.                    Files Included with QBSCR  . . . . . . . . . . .  3
  66.  
  67.                    A QBSCR Glossary . . . . . . . . . . . . . . . .  4
  68.  
  69.                    A Synopsis of the QBSCR Screen Routines  . . . .  8
  70.  
  71.                    The SCREEN BUILDER Program . . . . . . . . . . . 12
  72.  
  73.                    The DEMO Program . . . . . . . . . . . . . . . . 13
  74.  
  75.                    The REF Program  . . . . . . . . . . . . . . . . 14
  76.  
  77.                    The COLCONST.BAS file  . . . . . . . . . . . . . 17
  78.  
  79.                    Incorporating the Screen Routines
  80.                         into Your Own Programs  . . . . . . . . . . 18
  81.  
  82.                    The QBSCR Routines Detailed Descriptions . . . . 22
  83.  
  84.                    Subprogram BANNER  . . . . . . . . . . . . . . . 23
  85.  
  86.                    Function BLOCKSIZE . . . . . . . . . . . . . . . 25
  87.  
  88.                    Subprogram BLOCKRESTORE  . . . . . . . . . . . . 26
  89.  
  90.                    Subprogram BLOCKSAVE . . . . . . . . . . . . . . 28
  91.  
  92.                    Subprogram BUILDSCREEN . . . . . . . . . . . . . 30
  93.  
  94.                    Subprogram CENTER  . . . . . . . . . . . . . . . 32
  95.  
  96.                    Subprogram CLRSCR  . . . . . . . . . . . . . . . 33
  97.  
  98.                    Function COLORCHK  . . . . . . . . . . . . . . . 34
  99.  
  100.                    Function GETBACKGROUND . . . . . . . . . . . . . 35
  101.  
  102.                    Function GETFOREGROUND . . . . . . . . . . . . . 36
  103.  
  104.                    Subprogram GETSCREEN . . . . . . . . . . . . . . 37
  105.  
  106.                    Function GETSTRING . . . . . . . . . . . . . . . 38
  107.  
  108.                    Function GETVIDEOSEGMENT . . . . . . . . . . . . 40
  109.  
  110.  
  111.  
  112.  
  113.                                                                page ii
  114.  
  115.  
  116.  
  117.  
  118.          T A B L E   O F   C O N T E N T S   ( c o n ' d )
  119.          -------------------------------------------------------------
  120.  
  121.  
  122.                    Function MAKEMENU  . . . . . . . . . . . . . . . 42
  123.  
  124.                    Subprogram MAKEWINDOW  . . . . . . . . . . . . . 48
  125.  
  126.                    Subprogram MULTIMENU . . . . . . . . . . . . . . 55
  127.  
  128.                    Subprogram OFFCENTER . . . . . . . . . . . . . . 64
  129.  
  130.                    Subprogram PUTSCREEN . . . . . . . . . . . . . . 65
  131.  
  132.                    Subprogram QBPRINT . . . . . . . . . . . . . . . 66
  133.  
  134.                    Function SCREENBLANK . . . . . . . . . . . . . . 68
  135.  
  136.                    Subprogram SCRNRESTORE . . . . . . . . . . . . . 70
  137.  
  138.                    Subprogram SCRNSAVE  . . . . . . . . . . . . . . 72
  139.  
  140.                    Subprogram WIPE  . . . . . . . . . . . . . . . . 74
  141.  
  142.                    Techniques for Using QBSCR . . . . . . . . . . . 76
  143.  
  144.                    Displaying and Popping a Window  . . . . . . . . 77
  145.  
  146.                    Visual Effects with BUILDSCREEN and CLRSCR . . . 80
  147.  
  148.                    Window Making Techniques . . . . . . . . . . . . 81
  149.  
  150.                    Menu Techniques  . . . . . . . . . . . . . . . . 82
  151.  
  152.                    Cross Reference - Routine Dependencies . . . . . 84
  153.  
  154.                    Closing Notes  . . . . . . . . . . . . . . . . . 85
  155.  
  156.                    Registration Form  . . . . . . . . . . . . . . . 86
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.                                                               page iii
  176.  
  177.  
  178.  
  179.  
  180.          Welcome to the QBSCR Screen Routines
  181.          -------------------------------------------------------------
  182.  
  183.                    The  QBSCR  Screen  Routines  is  a  collection  of
  184.                    utilities   for   the   discriminating   QuickBASIC
  185.                    programmer.  As the name implies, they  are  screen
  186.                    and display oriented.  With these routines and very
  187.                    little  effort,  your own programs can be extremely
  188.                    professional in appearance. They are quite easy  to
  189.                    use and incorporate into your own programs.
  190.  
  191.                    The Screen Routines are especially  useful  if  you
  192.                    are   in  a  hurry.   The  QBSCR  package  can  cut
  193.                    development time of any project in half, since  all
  194.                    the  display  routines are already written for you.
  195.                    Incorporate the QBSCR routines  into  your  program
  196.                    with  a  single  line of code, and all of the QBSCR
  197.                    resources are at your disposal.
  198.  
  199.                    The  screen  routines are more than just a toolbox,
  200.                    however. They can also fill the role of tutor.   By
  201.                    reading  through the source code of these routines,
  202.                    you will quickly find yourself learning how  to  do
  203.                    new things with QuickBASIC.
  204.  
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.                                                                 page 1
  238.  
  239.  
  240.  
  241.  
  242.          A Few Notices
  243.          -------------------------------------------------------------
  244.  
  245.  
  246.                    The QBSCR Screen Routines are made available to you
  247.                    through  the  concept  of  shareware.  Shareware is
  248.                    software   that   authors   encourage   others   to
  249.                    distribute  among  friends and colleagues.  In this
  250.                    way the author's software not only  becomes  widely
  251.                    known,  but  consumers  may  "try before they buy."
  252.                    Once they decide to keep and use the software, they
  253.                    send in a registration  fee,  or  payment  for  the
  254.                    software, to the author.
  255.  
  256.                    The Screen Routines  have  a  registration  fee  of
  257.                    $15.00.  If you decide to actually use the routines
  258.                    in  any of your programs, you should register them.
  259.                    As it can be very easy to forget  to  register,  or
  260.                    simply  ignore it, I provide you with an incentive.
  261.                    To any who register the QBSCR Screen  Routines  (or
  262.                    any  other  software products from BAD SOFTWARE), I
  263.                    will send  an  official  disk  set  containing  the
  264.                    latest  version  of the software, as well as a free
  265.                    program.   The   free   program   is   a   graphics
  266.                    entertainment  program  called LASER. This graphics
  267.                    program is fun to use and watch, and  can  also  be
  268.                    a great  stress management tool.  To all registered
  269.                    users of the QBSCR Screen Routines will go  a  copy
  270.                    of LASER.
  271.  
  272.                    If you decide to register the Screen Routines,  you
  273.                    can send a check for $15.00 made out to Tony Martin
  274.                    to  the  address  at the end of this document.  See
  275.                    the registration form on the last page for details.
  276.  
  277.                    This last notice is posted here for legal  reasons.
  278.                    You've   probably   seen   one  in  every  software
  279.                    package, but it's quite necessary.  Bear with me.
  280.  
  281.                    The QBSCR Screen routines are (C) Copyright 1989 by
  282.                    Tony Martin.  I retain all  rights  to  the  source
  283.                    code   and   documentation.    I   cannot  be  held
  284.                    responsible for any consequences arising  from  the
  285.                    ability or inability to use this software.  You may
  286.                    not  charge  money  of  any  kind for this software
  287.                    without prior written permission from  myself.   On
  288.                    the  other  hand,  I  don't  expect  any credits or
  289.                    royalties if you use these  routines  in  your  own
  290.                    software.
  291.  
  292.                    Let's now move on to the fun parts.
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.                                                                 page 2
  300.  
  301.  
  302.  
  303.  
  304.          Files Included with QBSCR
  305.          -------------------------------------------------------------
  306.  
  307.  
  308.                    There  are  several  files  included with the QBSCR
  309.                    Screen Routines.  Below is a list of the files  and
  310.                    a brief description of what each is.
  311.  
  312.  
  313.                    File...                              ...Description
  314.                    ---------------------------------------------------
  315.  
  316.                    QBSCR.BAS     The  source  code  for  the  routines
  317.                                  themselves.
  318.  
  319.                    QBSCR.DOC     The  documentation   file   you   are
  320.                                  reading now.
  321.  
  322.                    QBSCR.INC     An Include file that contains all the
  323.                                  necessary  DECLARE statements for the
  324.                                  QBSCR routines.
  325.  
  326.                    COLCONST.BAS  A  short  file of code to include  in
  327.                                  your  programs   that   use   colors.
  328.                                  Assigns   color   values   to   named
  329.                                  constants.
  330.  
  331.                    DEMO.BAS      Source code for a sample program that
  332.                                  illustrates how to  use  all  of  the
  333.                                  QBSCR routines.
  334.  
  335.                    DEMO.EXE      The DEMO  program  compiled,  linked,
  336.                                  and ready to run.
  337.  
  338.                    SB.EXE        The new Screen Builder program,  used
  339.                                  to create premade screen displays.
  340.  
  341.                    *.CLR         Color  versions  of  premade   screen
  342.                                  displays,   mostly   for   the   DEMO
  343.                                  program.
  344.  
  345.                    *.MON         Monochrome versions of premade screen
  346.                                  displays,   mostly   for   the   DEMO
  347.                                  program.
  348.  
  349.                    REF.BAS       An example of a real-life application
  350.                                  program  that  makes  good use of the
  351.                                  Screen Routines.
  352.  
  353.                    REF.EXE       The REF program compiled, linked, and
  354.                                  ready to run.
  355.  
  356.                    WHATS.NEW     Describes the revision history of the
  357.                                  QBSCR Screen Routines.
  358.  
  359.  
  360.  
  361.                                                                 page 3
  362.  
  363.  
  364.  
  365.  
  366.          A QBSCR Glossary
  367.          -------------------------------------------------------------
  368.  
  369.  
  370.                    There  are  a  few terms used in this documentation
  371.                    particular to the QBSCR  Screen  Routines  and  the
  372.                    functions   employed   within  the  package.   This
  373.                    section is a short  glossary  that  will  hopefully
  374.                    clarify the meanings of these terms with respect to
  375.                    this software.
  376.  
  377.  
  378.                    ASCII (characters)
  379.                    ---------------------------------------------------
  380.                         ASCII is an acronym for American Standard Code
  381.                         for Information Interchange.  It refers to the
  382.                         standard character set found on computers that
  383.                         support it.  IBM PCs and compatibles are ASCII
  384.                         machines.  The characters  are  referenced  by
  385.                         number   and   are  limited  to  256  possible
  386.                         characters  (0  -  255).   The  standard  only
  387.                         applies  to  characters  0  through  127.  The
  388.                         characters 128 through 255 are  left  open  to
  389.                         the  machine  builder.   IBM chose to create a
  390.                         set of box drawing characters as part  of  the
  391.                         extended characters, and we use them to create
  392.                         window frames.
  393.  
  394.  
  395.                    Burn-in
  396.                    ---------------------------------------------------
  397.                         When  an image is left on a display screen for
  398.                         a long period of time, the screen can retain a
  399.                         permanent ghost of this image.   The  phosphor
  400.                         inside  your  monitor  that  glows  to produce
  401.                         characters on your screen will have this image
  402.                         more or less permanently etched into it.  This
  403.                         is called screen Burn-in.  It usually requires
  404.                         the  same  image to be displayed eight hours a
  405.                         day over a period of  several  months.  It  is
  406.                         best avoided.
  407.  
  408.  
  409.                    DECLARE Statement
  410.                    ---------------------------------------------------
  411.                         A DECLARE statement is a  standard  QuickBASIC
  412.                         statement.   It  is not executable, meaning it
  413.                         tells the compiler something when the  program
  414.                         is   compiled,  and  really  does  nothing  at
  415.                         runtime.  The DECLARE  statement  is  used  to
  416.                         tell    the    compiler    information   about
  417.                         subprograms and functions before  it  gets  to
  418.                         them.   Using the DECLARE statement allows you
  419.  
  420.  
  421.  
  422.  
  423.                                                                 page 4
  424.  
  425.  
  426.  
  427.  
  428.                         to  utilize  your  subprograms  and  functions
  429.                         without the use of the CALL statement.  If you
  430.                         had  a subprogram called Clock which displayed
  431.                         the time in the  upper  left  corner  of  your
  432.                         screen,  you would have to issue the following
  433.                         statement in your program:
  434.  
  435.                                           CALL Clock
  436.  
  437.                         You could create a DECLARE  statement  for  it
  438.                         and place it at the beginning of your program.
  439.                         It would look like this:
  440.  
  441.                                      DECLARE SUB Clock ()
  442.  
  443.                         It  would  allow you to use your Clock routine
  444.                         by simply issuing the statement
  445.  
  446.                                             Clock
  447.  
  448.                         in your program.
  449.  
  450.  
  451.                    Display Memory
  452.                    ---------------------------------------------------
  453.                         Display memory is the physical  memory  inside
  454.                         your  computer,  specifically on your graphics
  455.                         card,  that  stores   the  contents   of   the
  456.                         display.   By knowing where this memory begins
  457.                         in terms of memory  addresses,  you  can  peek
  458.                         there   and  see  what's  on  the screen.  The
  459.                         SCRNSAVE   and   SCRNRESTORE   routines   rely
  460.                         entirely  on  the  contents  of this memory to
  461.                         save and restore information from and  to  the
  462.                         screen.
  463.  
  464.  
  465.                    Explode
  466.                    ---------------------------------------------------
  467.                         Explode,  when  used  in the context of screen
  468.                         windows, is a display  effect.   If  a  window
  469.                         explodes   onto  the  screen,  it  appears  to
  470.                         rapidly expand outward  from  nothing  to  its
  471.                         full size.
  472.  
  473.  
  474.                    Frame
  475.                    ---------------------------------------------------
  476.                         A  frame  is  simply a border around a window.
  477.                         It is drawn with standard IBM  extended  ASCII
  478.                         graphics characters.
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.                                                                 page 5
  486.  
  487.  
  488.  
  489.                    Highlight(ed)
  490.                    ---------------------------------------------------
  491.                         Highlight(ed)  refers to a character or set of
  492.                         characters that stand out from others  on  the
  493.                         screen.  This is generally done by making them
  494.                         brighter  or  a different color.  Highlighting
  495.                         is  used  to   call   attention   to   certain
  496.                         character(s),   indicating   that   they   are
  497.                         especially   significant.    In   the    QBSCR
  498.                         routines,   the   "Quick   Access"   keys  are
  499.                         highlighted so they are easily recognized.
  500.  
  501.  
  502.                    Menu
  503.                    ---------------------------------------------------
  504.                         A  menu  is  a  list  of 2 or more choices, or
  505.                         entries, from which a single entry  is  chosen
  506.                         by  a  user.   The  method of selection varies
  507.                         from program to program. In the  QBSCR  Screen
  508.                         Routines, selection is made either by use of a
  509.                         selection bar or "Quick Access" keys.
  510.  
  511.  
  512.                    "Quick Access" Key
  513.                    ---------------------------------------------------
  514.                         A "Quick Access" key is  a  key  you  can  hit
  515.                         within a menu to give you direct access to any
  516.                         given entry.  Each menu entry (or choice) will
  517.                         have associated with it a unique key that will
  518.                         provide  this  direct access.  The key must be
  519.                         one of the letters that make up  the  text  of
  520.                         the  entry.   The  "Quick Access" key for each
  521.                         entry will be highlighted  to  indicate  which
  522.                         letter is the "Quick Access" key.
  523.  
  524.  
  525.                    Quick Library
  526.                    ---------------------------------------------------
  527.                         A Quick Library is a collection of routines in
  528.                         a   special  format,  like  the  QBSCR  Screen
  529.                         Routines, that can be  used  to  run  programs
  530.                         from  inside  the  QuickBASIC environment.  It
  531.                         has  a  .QLB   extension.    Refer   to   your
  532.                         QuickBASIC  documentation  for  information on
  533.                         how to create them.
  534.  
  535.  
  536.                    Parameter
  537.                    ---------------------------------------------------
  538.                         A  parameter is a piece of information that is
  539.                         passed to a subprogram  or  a  function.   For
  540.                         example,   the  QBSCR  routine  CENTER,  which
  541.                         centers text on any given row of  the  screen,
  542.                         must  know  two  pieces  of  information:  the
  543.                         string of text you want centered, and the  row
  544.                         of the screen on which to center it. Thus, the
  545.                         CENTER routine requires two parameters.
  546.  
  547.                                                                 page 6
  548.  
  549.  
  550.  
  551.                    Premade Display (or screen)
  552.                    ---------------------------------------------------
  553.                         When you see premade display in this document,
  554.                         what is being referred to is a screen that was
  555.                         made using the Screen Builder program included
  556.                         with   this   release   of  the  QBSCR  Screen
  557.                         Routines.
  558.  
  559.  
  560.                    Runtime Library
  561.                    ---------------------------------------------------
  562.                         A  runtime library is a collection of routines
  563.                         in a special format,  like  the  QBSCR  Screen
  564.                         Routines,  that  the  Microsoft Linker uses to
  565.                         create your executable program.  While a Quick
  566.                         Library is used  to  run  your  programs  from
  567.                         inside  the  QuickBASIC environment, a runtime
  568.                         library is used to run your program from  DOS,
  569.                         or outside the QuickBASIC environment.
  570.  
  571.  
  572.                    Selection Bar
  573.                    ---------------------------------------------------
  574.                         A  selection bar is a mechanism used to select
  575.                         entries from a menu.  In a  menu,  one  of the
  576.                         entries   will   be  highlighted  in  a  color
  577.                         different from the other  entries.   It  looks
  578.                         like  a  bar  of  a  different  color has been
  579.                         placed over the  entry,  so  it  is  called  a
  580.                         selection  bar.   Hitting the ENTER key causes
  581.                         the entry that is currently highlighted by the
  582.                         selection bar to be returned  to  the  calling
  583.                         routine.
  584.  
  585.  
  586.                    Shadow (window)
  587.                    ---------------------------------------------------
  588.                         A  shadow  is  simply a dark edging around two
  589.                         sides of a window.  It creates a  3-D  effect,
  590.                         making the window look like it is sitting away
  591.                         from the screen.
  592.  
  593.  
  594.                    Window
  595.                    ---------------------------------------------------
  596.                         A window is an area of the screen that is  set
  597.                         off  from the rest in some fashion, usually by
  598.                         displaying a box around  that  area.   Windows
  599.                         are  excellent  tools for isolating ideas on a
  600.                         common display.
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.                                                                 page 7
  610.  
  611.  
  612.  
  613.  
  614.          A Synopsis of the QBSCR Screen Routines
  615.          -------------------------------------------------------------
  616.  
  617.  
  618.                    Before  we  get  into the implementation details of
  619.                    the QBSCR Screen Routines, take a quick look at the
  620.                    summary of the routines included with the package.
  621.  
  622.  
  623.                    Subprogram BANNER
  624.                    ---------------------------------------------------
  625.                    This routine will create a scrolling banner on  any
  626.                    line  of  the  screen.   The effect is similar to a
  627.                    Hollywood theater  scrolling  marquis,  advertising
  628.                    the latest show.
  629.  
  630.  
  631.                    Function BLOCKSIZE
  632.                    ---------------------------------------------------
  633.                    The BlockSize function is used as a calculation aid
  634.                    for  the  BlockSave  and  BlockRestore subprograms,
  635.                    listed below.  It will calculate the  exact  number
  636.                    of  elements  required  for  an  array  to use with
  637.                    BlockSave and  BlockRestore.   This  function  will
  638.                    prove  its  value  as  you  begin  to use these two
  639.                    subprograms.
  640.  
  641.  
  642.                    Subprogram BLOCKRESTORE
  643.                    ---------------------------------------------------
  644.                    The  BlockRestore   subprogram   will   restore   a
  645.                    rectangular  portion  of  the screen that was saved
  646.                    previously with the BlockSave  subprogram  (below).
  647.                    Use  BlockSave  to  save  part of the screen before
  648.                    overwriting it (with a window, perhaps),  and  then
  649.                    use  BlockRestore  to  replace  the  portion of the
  650.                    screen that was overwritten.
  651.  
  652.  
  653.                    Subprogram BLOCKSAVE
  654.                    ---------------------------------------------------
  655.                    The BlockSave subprogram will save a portion of the
  656.                    screen that you wish to overwrite  and  then  later
  657.                    restore (using BlockRestore, above).
  658.  
  659.  
  660.                    Subprogram BUILDSCREEN
  661.                    ---------------------------------------------------
  662.                    The  BuildScreen  subprogram  will  place a premade
  663.                    display (created with Screen Builder or  saved  via
  664.                    GetScreen)  onto  the screen in any of 16 different
  665.                    ways.  See the DEMO program for a demonstration.
  666.  
  667.  
  668.  
  669.  
  670.  
  671.                                                                 page 8
  672.  
  673.  
  674.  
  675.                    Subprogram CENTER
  676.                    ---------------------------------------------------
  677.                    This   routine   will   center  any  string  of  80
  678.                    characters or less  on  any  specific  row  of  the
  679.                    screen.
  680.  
  681.  
  682.                    Subprogram CLRSCR
  683.                    ---------------------------------------------------
  684.                    Designed  as  a  replacement for the CLS statement,
  685.                    this routine will clear the display screen  in  any
  686.                    of 16 different ways.
  687.  
  688.  
  689.                    Function COLORCHK
  690.                    ---------------------------------------------------
  691.                    This  function  is  used  to  determine whether the
  692.                    display  the  software  is  running  on  has  color
  693.                    capability  or  not.   The  function  returns  TRUE
  694.                    (Non-Zero) if the machine  can  display  color,  or
  695.                    FALSE (Zero) if it cannot.
  696.  
  697.  
  698.                    Function GETBACKGROUND
  699.                    ---------------------------------------------------
  700.                    This function will return the BASIC color value  of
  701.                    the background color of any location on the screen.
  702.  
  703.  
  704.                    Function GETFOREGROUND
  705.                    ---------------------------------------------------
  706.                    This function will return the BASIC color value  of
  707.                    the foreground color of any location on the screen.
  708.  
  709.  
  710.                    Subprogram GETSCREEN
  711.                    ---------------------------------------------------
  712.                    The  GetScreen  routine  will  save   the   current
  713.                    contents of the display to a disk file, in a format
  714.                    that   is   compatible  with  the  BuildScreen  and
  715.                    PutScreen routines, as well as the  Screen  Builder
  716.                    program.  Save is very fast (< 1 second).
  717.  
  718.  
  719.                    Function GETSTRING
  720.                    ---------------------------------------------------
  721.                    This  function is intended as a replacement for the
  722.                    BASIC INPUT statement.  It will allow the  user  to
  723.                    enter  a  string  of text much like INPUT, but with
  724.                    GETSTRING you can limit the length of the string as
  725.                    the user enters it.  With minor modification of the
  726.                    source code (change one line), you  can  limit  the
  727.                    actual characters the user is allowed to enter.
  728.  
  729.  
  730.  
  731.  
  732.  
  733.                                                                 page 9
  734.  
  735.  
  736.  
  737.                    Function GETVIDEOSEGMENT
  738.                    ---------------------------------------------------
  739.                    This  function  returns the starting address of the
  740.                    video card's display memory.   Use  before  calling
  741.                    SCRNSAVE  or  SCRNRESTORE  (below)  to  obtain  the
  742.                    proper address.  Easy to use, really!  See the DEMO
  743.                    program for a demonstration if  you  don't  believe
  744.                    me.
  745.  
  746.  
  747.                    Function MAKEMENU
  748.                    ---------------------------------------------------
  749.                    This  function  will create a list-like menu on the
  750.                    screen and allow the user to choose an entry.   The
  751.                    function  returns  a  numerical  value equal to the
  752.                    chosen entry's position in the list.   It  provides
  753.                    two  mechanisms  to  select entries: 1) A scrolling
  754.                    selection bar, and 2) "Quick  Access"  keys.   Both
  755.                    mechanisms are implemented simultaneously.  See the
  756.                    DEMO program for a demonstration.
  757.  
  758.  
  759.                    Subprogram MAKEWINDOW
  760.                    ---------------------------------------------------
  761.                    This  versatile  routine will create windows on the
  762.                    screen for  you.   It  will  display  10  different
  763.                    window  types, 6 different frame types, can explode
  764.                    windows onto the screen  in  3  modes,  add  window
  765.                    shadows, and more.
  766.  
  767.  
  768.                    Subprogram MULTIMENU
  769.                    ---------------------------------------------------
  770.                    The MultiMenu subprogram  will  create  a  multiple
  771.                    menu,  pull-down  menu interface for your programs,
  772.                    very  much  like  the  pull-down   menus   in   the
  773.                    QuickBASIC environment.  Easy to set up and use.
  774.  
  775.  
  776.                    Subprogram OFFCENTER
  777.                    ---------------------------------------------------
  778.                    Allows you to center text between two columns on  a
  779.                    line  that  are not necessarily centered themselves
  780.                    with respect to the screen.  For instance,  if  you
  781.                    placed  a  window  on the right side of the screen,
  782.                    simply tell OFFCENTER the sides of the window,  and
  783.                    it will center text between those two columns.
  784.  
  785.  
  786.                    Subprogram PUTSCREEN
  787.                    ---------------------------------------------------
  788.                    This  routine will load from disk a premade display
  789.                    that was created with either the GetScreen  routine
  790.                    (above)  or  the  Screen Builder program.  Load and
  791.                    display is very fast (< 1 second).
  792.  
  793.  
  794.  
  795.                                                                page 10
  796.  
  797.  
  798.  
  799.                    Subprogram QBPRINT
  800.                    ---------------------------------------------------
  801.                    This  routine  will  place  a  text  string  on the
  802.                    display at the  position  specified  in  the  color
  803.                    specified.   Unlike  the  PRINT  statement, QBPrint
  804.                    writes directly to video memory  and  will  display
  805.                    characters  like  ASCII  7,  the  round bullet, and
  806.                    others as well.
  807.  
  808.  
  809.                    Function SCREENBLANK
  810.                    ---------------------------------------------------
  811.                    This  function,  when  called, blanks the screen of
  812.                    your display, and shows a short message  explaining
  813.                    that  the  screen  has  been blanked. When a key is
  814.                    pressed,  ScreenBlank  terminates  and  control  is
  815.                    returned  to  the  calling routine.  To prevent the
  816.                    short message from "burning-in" to the monitor,  it
  817.                    changes  place periodically.  This function returns
  818.                    the key that was pressed to restore the display, in
  819.                    case you want to use it.
  820.  
  821.  
  822.                    Subprogram SCRNRESTORE
  823.                    ---------------------------------------------------
  824.                    This routine will restore all or a portion  of  the
  825.                    display  that  has  been  saved  with  the SCRNSAVE
  826.                    routine.  When used  with  SCRNSAVE,  this  routine
  827.                    provides unbeatable results.
  828.  
  829.  
  830.                    Subprogram SCRNSAVE
  831.                    ---------------------------------------------------
  832.                    This  routine  will  save  a  portion or all of the
  833.                    current display screen.  When used  in  conjunction
  834.                    with the SCRNRESTORE routine, SCRNSAVE provides the
  835.                    capability  to  "pop"  parts  of  a  display,  like
  836.                    windows, error messages, menus, etc., to  and  from
  837.                    the screen.
  838.  
  839.  
  840.                    Subprogram WIPE
  841.                    ---------------------------------------------------
  842.                    This   routine   clears  out  a  programmer-defined
  843.                    portion of the display.  Excellent for erasing  the
  844.                    text from windows.
  845.  
  846.  
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856.  
  857.                                                                page 11
  858.  
  859.  
  860.  
  861.  
  862.          The SCREEN BUILDER Program
  863.          -------------------------------------------------------------
  864.  
  865.  
  866.                    Screen Builder is a new companion  program  to  the
  867.                    QBSCR  Screen  Routines.   With the introduction of
  868.                    BuildScreen in version 1.4, it  was  realized  that
  869.                    the  concept  of  placing  a  premade screen on the
  870.                    display in interesting ways was a nifty idea.   The
  871.                    problem was in its implementation.  Dealing with an
  872.                    array of 25 lines was unwieldy at best. Neither was
  873.                    it  acceptable  to be dealing only with two colors.
  874.                    Enter Screen Builder.
  875.  
  876.                    Screen Builder is an interactive screen editor.  It
  877.                    will allow you to  easily  create  multicolor  text
  878.                    screens  as  complicated  or as simple as you like.
  879.                    It has  tools  to  let  you  enter  extended  ASCII
  880.                    graphics  characters, perform block operations, and
  881.                    lots of other goodies.  It saves your screen  files
  882.                    in  a  format  specific  to  BASIC,  and allows the
  883.                    BuildScreen (and PutScreen) routines to access your
  884.                    screen files.
  885.  
  886.                    Now with Screen Builder, you can quickly and easily
  887.                    create attractive screens for  your  programs,  and
  888.                    display  them  quickly  (using  PutScreen) or in an
  889.                    interesting way (using  BuildScreen).   Tools  like
  890.                    Screen   Builder   have   sold  for  much  more  by
  891.                    themselves.  It is included as part  of  the  QBSCR
  892.                    Screen Routines package.
  893.  
  894.                    For  detailed  information  on the capabilities and
  895.                    usage  of  Screen  Builder,  refer  to  the  Screen
  896.                    Builder documentation.
  897.  
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.                                                                page 12
  920.  
  921.  
  922.  
  923.  
  924.          The DEMO Program
  925.          -------------------------------------------------------------
  926.  
  927.  
  928.                    Included with the QBSCR package is a program called
  929.                    DEMO.  Source code for the program is  included  as
  930.                    well.
  931.  
  932.                    DEMO is a demonstration  program  that  illustrates
  933.                    the use of each of the routines in the QBSCR Screen
  934.                    Routine   library.    One   of  the  best  learning
  935.                    techniques for using  the  Screen  Routines  is  to
  936.                    execute  this program, and as it runs, follow along
  937.                    in the source code to see what's happening and  how
  938.                    it's being done.
  939.  
  940.                    To run the DEMO program, make sure  that  the  file
  941.                    DEMO.EXE  and  all the *.CLR or *.MON files (CLR if
  942.                    you have a color display, MON if you  have  a  mono
  943.                    display)  are  in  the  same  place (i.e., the same
  944.                    drive and subdirectory).  Then enter the  following
  945.                    command at the DOS prompt:
  946.  
  947.                                           DEMO
  948.  
  949.                    The program will begin executing and you can see in
  950.                    the source code what's  happening.   Simply  follow
  951.                    the on-screen directions.
  952.  
  953.                    The source code for DEMO is  fully  documented  and
  954.                    can even be used as a quick reference on the syntax
  955.                    of each routine.  A good thing to keep handy as you
  956.                    program.
  957.  
  958.  
  959.  
  960.  
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979.  
  980.  
  981.                                                                page 13
  982.  
  983.  
  984.  
  985.  
  986.          The REF Program
  987.          -------------------------------------------------------------
  988.  
  989.  
  990.                    The QBSCR Screen Routines are packaged with a  free
  991.                    program  called  REF.  REF is a computer-based tool
  992.                    that  can  be  used   as   a   reference   to   the
  993.                    often-looked-up portions of the Screen Routines. It
  994.                    will  tell  you  all the window types, frame types,
  995.                    and explode types for the  MakeWindow  routine,  as
  996.                    well  as  all ClrScr and BuildScreen modes.  Source
  997.                    code for REF is also included with QBSCR.
  998.  
  999.                    To  run  REF,  make  sure  the  files  REF.EXE  and
  1000.                    TESTSCR.* are in the same  place  (i.e.,  the  same
  1001.                    drive  and  subdirectory),  and issue the following
  1002.                    command at the DOS prompt:
  1003.  
  1004.                                            REF
  1005.  
  1006.                    The program will execute and you will see its menu.
  1007.                    To  select  one  of the menu entries, use the arrow
  1008.                    keys to highlight the selection of your choice, and
  1009.                    hit ENTER. Notice, however, that  each  menu  entry
  1010.                    has a single letter within it highlighted.  This is
  1011.                    the  "Quick  Access"  key for that menu entry.  You
  1012.                    may use the "Quick  Access"  keys  by  hitting  the
  1013.                    highlighted letter associated with the selection of
  1014.                    your choice.  Each REF function is detailed below.
  1015.  
  1016.  
  1017.                    Window Types
  1018.                    ---------------------------------------------------
  1019.                    The  Window  Types  function  will  display all the
  1020.                    possible values of the WindowType parameter for the
  1021.                    MakeWindow subprogram.  Select this  function  from
  1022.                    the  menu by highlighting it with the selection bar
  1023.                    and hitting ENTER, or hitting the W "Quick  Access"
  1024.                    key.   REF  will  then  show  you a screen with ten
  1025.                    different windows and some explanatory text. Within
  1026.                    each window is a number which  corresponds  to  the
  1027.                    value  used  for the WindowType parameter that will
  1028.                    create that type of window.  Once  you've  finished
  1029.                    looking over the information, you can return to the
  1030.                    menu by hitting any key.
  1031.  
  1032.  
  1033.                    Frame Types
  1034.                    ---------------------------------------------------
  1035.                    Frames are what define or draw  your  windows.   On
  1036.                    the  IBM  PC  and  its derivatives,  you  can  have
  1037.                    several  combinations  of  single  and  double line
  1038.                    frames. This function of REF  will  show  you  what
  1039.                    value  of  the  FrameType  parameter will result in
  1040.                    what type of frame.  Select this function from  the
  1041.  
  1042.  
  1043.                                                                page 14
  1044.  
  1045.  
  1046.                    menu  by highlighting it with the selection bar and
  1047.                    hitting ENTER, or hitting the F "Quick Access" key.
  1048.                    REF will then show you a screen displaying the  six
  1049.                    possible  frame  types  and the FrameType parameter
  1050.                    values used to attain them.  Once  you've  finished
  1051.                    looking over the information, you can return to the
  1052.                    menu by hitting any key.
  1053.  
  1054.  
  1055.                    Explode Types
  1056.                    ---------------------------------------------------
  1057.                    The   Explode  Type  parameter  of  the  MakeWindow
  1058.                    subprogram defines how your window will  be  placed
  1059.                    on  the  screen.   You  can  simply  have  it drawn
  1060.                    normally, or have it "exploded" onto the screen  in
  1061.                    one   of   several   ways.   This  portion  of  REF
  1062.                    demonstrates the three Explode Types and tells  you
  1063.                    which  parameter value corresponds to which explode
  1064.                    type.  Select the Explode Type function of REF from
  1065.                    the menu by highlighting it with the selection  bar
  1066.                    and  hitting the ENTER key, or hitting the E "Quick
  1067.                    Access"  key.   REF  will  demonstrate  the   three
  1068.                    explode  types  with  sample windows on the screen.
  1069.                    Simply follow the on-screen directions.   Once  REF
  1070.                    has shown you the last explode type, you may return
  1071.                    to the menu by hitting any key.
  1072.  
  1073.  
  1074.                    ClrScr Modes
  1075.                    ---------------------------------------------------
  1076.                    The ClrScr function will clear your screen  in  any
  1077.                    of  sixteen  different modes.  Each mode clears the
  1078.                    screen in a different way, resulting in a different
  1079.                    sort of "animation".  This  function  of  REF  will
  1080.                    demonstrate  any  of the sixteen modes.  Select the
  1081.                    ClrScr Modes function  of  REF  from  the  menu  by
  1082.                    highlighting  it with the selection bar and hitting
  1083.                    ENTER, or by hitting the C "Quick Access" key.  You
  1084.                    will then see the screen filled with the ASCII  176
  1085.                    character  (a shaded rectangle), and a small window
  1086.                    in the center of the screen.  In this window, enter
  1087.                    a number from 0 to 15 (inclusive), indicating which
  1088.                    ClrScr mode you would like to see.   Once  you  hit
  1089.                    the ENTER key, REF will demonstrate the ClrScr mode
  1090.                    you  indicated  and  then  pause.  You can then try
  1091.                    another mode by hitting any key.  REF will fill the
  1092.                    screen again and allow you to enter  another  mode.
  1093.                    If   you   have  finished  with  the  ClrScr  Modes
  1094.                    function, you can return to the menu by hitting the
  1095.                    ESC key.
  1096.  
  1097.  
  1098.                    BuildScreen Modes
  1099.                    ---------------------------------------------------
  1100.                    The BuildScreen function will place on  the  screen
  1101.                    an array of strings that define a display.  It will
  1102.                    place  your display on the screen in any of sixteen
  1103.                    different modes.  Each mode displays the screen  in
  1104.  
  1105.                                                                page 15
  1106.  
  1107.  
  1108.  
  1109.                    a  different  way, resulting in a different sort of
  1110.                    "animation." This function of REF will  demonstrate
  1111.                    any  of  the sixteen modes.  Select the BuildScreen
  1112.                    Modes function of REF from the menu by highlighting
  1113.                    it with the selection bar and hitting ENTER, or  by
  1114.                    hitting  the  B  "Quick Access" key.  You will then
  1115.                    see a blank screen  with  a  small  window  in  the
  1116.                    center  of  the  screen.   In  this window, enter a
  1117.                    number from 0 to 15 (inclusive),  indicating  which
  1118.                    BuildScreen  mode  you would like to see.  Once you
  1119.                    hit  the  ENTER  key,  REF  will  demonstrate   the
  1120.                    BuildScreen  mode  you  indicated,  and then pause.
  1121.                    You can then try another mode by hitting  any  key.
  1122.                    REF  will  clear  the screen again and allow you to
  1123.                    enter another mode. If you have finished  with  the
  1124.                    BuildScreen  Modes  function, you can return to the
  1125.                    menu by hitting the ESC key.  NOTE: The BuildScreen
  1126.                    portion  of  REF  requires  access  to   the   file
  1127.                    TESTSCR.CLR  (or  .MON).   This file must be in the
  1128.                    same place (i.e., same drive and  subdirectory)  as
  1129.                    the  REF  program  before  you  start  REF,  or the
  1130.                    program will terminate ungracefully.
  1131.  
  1132.  
  1133.                    Quit REF
  1134.                    ---------------------------------------------------
  1135.                    Once you have returned to the  menu  from  whatever
  1136.                    REF  functions  you needed to use, you may quit the
  1137.                    REF program by highlighting the Quit function  with
  1138.                    the  selection bar and hitting ENTER, or by hitting
  1139.                    the Q "Quick Access" key.  The  screen  will  clear
  1140.                    and you will be returned to DOS.
  1141.  
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155.  
  1156.  
  1157.  
  1158.  
  1159.  
  1160.  
  1161.  
  1162.  
  1163.  
  1164.  
  1165.  
  1166.  
  1167.                                                                page 16
  1168.  
  1169.  
  1170.  
  1171.  
  1172.          The COLCONST.BAS File
  1173.          -------------------------------------------------------------
  1174.  
  1175.  
  1176.                    Included with the QBSCR Screen Routines is a  short
  1177.                    file  of BASIC code that will make your programming
  1178.                    of colors much easier.  It's  called  COLCONST.BAS,
  1179.                    which is short for COLOR CONSTANTS.
  1180.  
  1181.                    What  it  consists  of  is a collection of CONSTant
  1182.                    declarations that assign  color  values  to  names.
  1183.                    For example, two of the lines look like this:
  1184.  
  1185.                                     CONST BLACK = 0
  1186.                                     CONST MAGENTA = 5
  1187.  
  1188.                    This  would  allow  you  to issue a color statement
  1189.                    that looks like this:
  1190.  
  1191.                                   COLOR MAGENTA, BLACK
  1192.  
  1193.                    This will improve  the  readability  of  your  code
  1194.                    immensely,  while  also  making  it  easier to code
  1195.                    colors into your program.  There are also constants
  1196.                    for the BRIGHT and BLINK attributes  that  you  can
  1197.                    combine  with  the  colors, as in this example that
  1198.                    produces a blinking Blue on a White background:
  1199.  
  1200.                                 COLOR BLINK + BLUE, WHITE
  1201.  
  1202.                    or this example that makes bright White  on  a  Red
  1203.                    background:
  1204.  
  1205.                                 COLOR BRIGHT + WHITE, RED
  1206.  
  1207.                    There  is also a predefined color called YELLOW, so
  1208.                    you don't have to say BRIGHT  +  BROWN.   Just  use
  1209.                    YELLOW.
  1210.  
  1211.                    To  incorporate  these  useful  constants  in  your
  1212.                    program, simply use the  QuickBASIC  MERGE  command
  1213.                    from the File menu...
  1214.  
  1215.                              1. Place the cursor at the  beginning  of
  1216.                                 your program...
  1217.  
  1218.                              2. Select the QuickBASIC File menu...
  1219.  
  1220.                              3. Select the MERGE function...
  1221.  
  1222.                              4. Enter  COLCONST.BAS in the file  field
  1223.                                 and hit ENTER.
  1224.  
  1225.                    The code for the color  constants  will  be  merged
  1226.                    into your program for easy use.
  1227.  
  1228.  
  1229.                                                                page 17
  1230.  
  1231.  
  1232.  
  1233.  
  1234.          Incorporating the Screen Routines
  1235.          into Your Own Programs
  1236.          -------------------------------------------------------------
  1237.  
  1238.  
  1239.                    There are several ways you can use the QBSCR Screen
  1240.                    Routines with your own programs.  Each  method  has
  1241.                    its  advantages  and  drawbacks.   You  must decide
  1242.                    which method is best for you based on  your  needs.
  1243.                    Each  method is detailed below, as well as its pros
  1244.                    and cons.
  1245.  
  1246.  
  1247.                    Method 1: MERGE
  1248.                    ---------------------------------------------------
  1249.                    The QuickBASIC editor has a MERGE function  on  its
  1250.                    Edit  menu.   Using  this  function, you can easily
  1251.                    merge the source code file  (QBSCR.BAS)  into  your
  1252.                    own  program.   Once  there,  you  can  delete  the
  1253.                    routines you don't plan to  use  in  your  program.
  1254.                    Before  you  go through wantonly deleting routines,
  1255.                    however, make sure that you check the  QBSCR  cross
  1256.                    reference  in the back of this manual, to make sure
  1257.                    you aren't deleting a routine that another  routine
  1258.                    depends  on.   By  merging,  the  routines become a
  1259.                    permanent part of your program.  The  benefits  are
  1260.                    that you don't have to worry about additional files
  1261.                    when  moving  the  source code of your program, and
  1262.                    you can neatly tailor the screen routines  to  suit
  1263.                    the  needs  of  your  particular program.  The main
  1264.                    drawback is that you are reducing the possible size
  1265.                    of your own source code by the size of  the  screen
  1266.                    routines.  QuickBASIC has a limited amount of space
  1267.                    available  for  such  things as strings and dynamic
  1268.                    arrays.  The more source code you have in your main
  1269.                    module, the more likely it becomes  that  you  will
  1270.                    have  to  go  to multiple modules.  This isn't bad,
  1271.                    but it defeats the purpose  of  merging  the  QBSCR
  1272.                    routines  into  your  own  program.  This method is
  1273.                    recommended if your program will not be too large.
  1274.  
  1275.                    To actually perform the merge, start QuickBASIC and
  1276.                    load  your  own  source  code  if  necessary.  Then
  1277.                    select the File menu, and the  Merge  option.   You
  1278.                    will be allowed to pick from a menu or enter a name
  1279.                    manually.  Select or enter
  1280.  
  1281.                                         QBSCR.BAS
  1282.  
  1283.                    and  the routines will be merged into your program.
  1284.                    All the DECLARE statements from the Screen Routines
  1285.                    will be placed in your program wherever you had the
  1286.                    cursor when you performed the merge, so  make  sure
  1287.                    the   cursor   is   where   you  want  the  DECLARE
  1288.                    statements.  You may now call  any  of  the  screen
  1289.  
  1290.  
  1291.                                                                page 18
  1292.  
  1293.  
  1294.  
  1295.                    routines you like, delete any of the ones you won't
  1296.                    be needing, or change them to suit your needs.
  1297.  
  1298.  
  1299.                    Method 2: LOAD
  1300.                    ---------------------------------------------------
  1301.                    The LOAD method is similar to the MERGE method, but
  1302.                    the QBSCR routines don't become a permanent part of
  1303.                    your  own program.  Using this method, you load the
  1304.                    QBSCR Screen Routines source code (QBSCR.BAS) as  a
  1305.                    separate   file.    When  your  program  is  saved,
  1306.                    QuickBASIC will create a .MAK file, which  contains
  1307.                    the  names  of all files in memory when the program
  1308.                    was saved.  QuickBASIC then uses this file to  tell
  1309.                    it  what  files to load when you open your program.
  1310.                    Advantages of this method are that  you  have  more
  1311.                    available  memory  for your own source code and the
  1312.                    Screen Routines are kept in a separate "package" or
  1313.                    file which aids program clarity. You can delete  or
  1314.                    change  the  QBSCR  routines  as easily as with the
  1315.                    MERGE option above (but make SURE you  are  working
  1316.                    with  a  COPY of the QBSCR.BAS file, as the changes
  1317.                    you make become  permanent).   Problems  with  this
  1318.                    method are  mostly  convenience-oriented.   Loading
  1319.                    your   program   into  QuickBASIC,  compiling  your
  1320.                    program, and execution of your program (inside  the
  1321.                    environment  ONLY)  are  all  slower  than the next
  1322.                    method, using the Quick Library.
  1323.  
  1324.                    To  load  the  QBSCR  Screen  Routines  using  this
  1325.                    method, start QuickBASIC and load your own  program
  1326.                    if  necessary.   Then select the File menu, and the
  1327.                    Load option.  You  will  then  be  able  to  either
  1328.                    select  from  a  list  or  enter the name manually.
  1329.                    Enter
  1330.  
  1331.                                         QBSCR.BAS
  1332.  
  1333.                    and  QuickBASIC  will  load  the file as a separate
  1334.                    module.  Once this is done, you can see  QBSCR  and
  1335.                    all its routines by hitting the F2 key.  To use the
  1336.                    routines,  you  will need to make sure your program
  1337.                    has all the appropriate DECLARE statements from the
  1338.                    Screen Routines.  You can either copy  the  DECLARE
  1339.                    statements  from  the QBSCR module over to your own
  1340.                    program  using  the  environment editor, or you can
  1341.                    place the following statement at the  top  of  your
  1342.                    own program:
  1343.  
  1344.                                 REM $Include: 'QBSCR.INC'
  1345.  
  1346.                    This will cause  the  compiler  to  load  the  file
  1347.                    QBSCR.INC  into  your module at compile time.  This
  1348.                    file contains all the DECLARE  statements  for  the
  1349.                    QBSCR  Screen  Routines.   The  file must be in the
  1350.                    same drive and subdirectory as QuickBASIC.
  1351.  
  1352.  
  1353.                                                                page 19
  1354.  
  1355.  
  1356.  
  1357.                    You can now use any or all of the Screen  Routines,
  1358.                    delete  the  ones you don't need, or change them to
  1359.                    suit your needs.  If you copy your source  code  to
  1360.                    another  disk or subdirectory, don't forget to copy
  1361.                    the files QBSCR.BAS, QBSCR.INC  (if  you  used  the
  1362.                    $Include  statement  above),  and the .MAK file for
  1363.                    your program.
  1364.  
  1365.  
  1366.                    Method 3: Use the Quick Library
  1367.                    ---------------------------------------------------
  1368.                    To use the Quick Library method, you  must  have  a
  1369.                    Quick  Library  form  of  the  QBSCR  routines.  To
  1370.                    create  the  QuickLibrary  for  the  QBSCR   Screen
  1371.                    Routines, load QBSCR.BAS into QuickBASIC by itself.
  1372.                    Then choose the "Make Library" option from the  Run
  1373.                    menu.   QuickBASIC  will  then  go through a normal
  1374.                    compile, and then create two library files.  The  2
  1375.                    files  generated,  QBSCR.QLB and QBSCR.LIB, need to
  1376.                    be on the same drive and in the  same  subdirectory
  1377.                    as   QuickBASIC.   Using  this  method,  you  start
  1378.                    QuickBASIC with a /L  parameter,  followed  by  the
  1379.                    library  to use.  Advantages are mostly convenience
  1380.                    oriented.  They include faster loading,  compiling,
  1381.                    linking  and environment-execution of your program.
  1382.                    The primary disadvantage is that you cannot  modify
  1383.                    the QBSCR routines in any way from the environment.
  1384.  
  1385.                    To use the  QBSCR  Screen  Routines  in  the  Quick
  1386.                    Library   format,   start   QuickBASIC   using  the
  1387.                    following command (where you would  replace  MYPROG
  1388.                    with the actual name of your program):
  1389.  
  1390.                                    QB MYPROG /L QBSCR
  1391.  
  1392.                    This will cause QuickBASIC  to  load  your  program
  1393.                    along  with  the  Quick Library QBSCR.  Once inside
  1394.                    the QuickBASIC environment, you will also  need  to
  1395.                    make  sure  your  program  has  all the appropriate
  1396.                    DECLARE statements from the Screen  Routines.   You
  1397.                    can  place  the  following  statement at the top of
  1398.                    your own program:
  1399.  
  1400.                                 REM $Include: 'QBSCR.INC'
  1401.  
  1402.                    This will cause  the  compiler  to  load  the  file
  1403.                    QBSCR.INC  into  your module at compile time.  This
  1404.                    file contains all the DECLARE  statements  for  the
  1405.                    QBSCR  Screen  Routines.   The  file must be in the
  1406.                    same drive and subdirectory as QuickBASIC.
  1407.  
  1408.                    Your  program  now  has  access to all of the QBSCR
  1409.                    Screen Routines.
  1410.  
  1411.  
  1412.  
  1413.  
  1414.  
  1415.                                                                page 20
  1416.  
  1417.  
  1418.  
  1419.                    Summary of Incorporation Methods
  1420.                    ---------------------------------------------------
  1421.                    It  has  been my experience that method 2, LOAD, is
  1422.                    the most generally useful of the three methods. Use
  1423.                    method 1, MERGE, if your program will be  small  to
  1424.                    medium  sized.  Use method 3, the Quick Library, if
  1425.                    you are in  a  particular  hurry  to  develop  your
  1426.                    program,  as  it loads and compiles faster, as well
  1427.                    as executing inside the environment faster.
  1428.  
  1429.                    As far as the final standalone  executable  program
  1430.                    is concerned, all three methods create equally fast
  1431.                    code.   The  first  two  methods  may  be better if
  1432.                    executable size is important to  you,  as  you  can
  1433.                    edit out the routines your program doesn't actually
  1434.                    use.
  1435.  
  1436.  
  1437.  
  1438.  
  1439.  
  1440.  
  1441.  
  1442.  
  1443.  
  1444.  
  1445.  
  1446.  
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455.  
  1456.  
  1457.  
  1458.  
  1459.  
  1460.  
  1461.  
  1462.  
  1463.  
  1464.  
  1465.  
  1466.  
  1467.  
  1468.  
  1469.  
  1470.  
  1471.  
  1472.  
  1473.  
  1474.  
  1475.  
  1476.  
  1477.                                                                page 21
  1478.  
  1479.  
  1480.  
  1481.  
  1482.          The QBSCR Routines Detailed Descriptions
  1483.          -------------------------------------------------------------
  1484.  
  1485.  
  1486.                    We  are about to enter the detailed descriptions of
  1487.                    each of the QBSCR Screen Routines, and I thought  I
  1488.                    might warn you what to expect.
  1489.  
  1490.                    For each of the routines, the following information
  1491.                    will be provided:
  1492.  
  1493.  
  1494.                         ■ The NAME of the routine
  1495.  
  1496.                         ■ The PURPOSE of the routine
  1497.  
  1498.                         ■ The USAGE of the routine
  1499.  
  1500.                         ■ A description of each PARAMETER the  routine
  1501.                           requires
  1502.  
  1503.                         ■ A DESCRIPTION of the routine, including  any
  1504.                           relevant notes
  1505.  
  1506.                         ■ An EXAMPLE of the use of the routine
  1507.  
  1508.                         ■ Any known limitations of the routine
  1509.  
  1510.  
  1511.                    Each  routine  and it's related information will be
  1512.                    presented on it's own  page.   If  the  description
  1513.                    runs  over  onto  a  second or third page, the next
  1514.                    routine description will start on a new page.  This
  1515.                    will help keep things organized and  easy  to  deal
  1516.                    with.
  1517.  
  1518.  
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524.  
  1525.  
  1526.  
  1527.  
  1528.  
  1529.  
  1530.  
  1531.  
  1532.  
  1533.  
  1534.  
  1535.  
  1536.  
  1537.  
  1538.  
  1539.                                                                page 22
  1540.  
  1541.  
  1542.  
  1543.  
  1544.          Subprogram BANNER
  1545.          -------------------------------------------------------------
  1546.  
  1547.  
  1548.                    Purpose: To create a scrolling banner effect with a
  1549.                    single string on any line of the display.
  1550.  
  1551.  
  1552.                    Usage: Banner st$, row%
  1553.  
  1554.                              st$  - the  text  string  to  make into a
  1555.                                     banner.
  1556.                              row% - the row of the screen on which  to
  1557.                                     make the banner.
  1558.  
  1559.  
  1560.                    Details: The  Banner  routine  will  not  create  a
  1561.                    scrolling banner with a single call.  The scrolling
  1562.                    effect  is achieved through continuous calls to the
  1563.                    routine.  A single call to Banner will:
  1564.  
  1565.                         1) Remove the first letter from the  left  end
  1566.                            of the string,
  1567.  
  1568.                         2) Shift all remaining characters one position
  1569.                            to the left,
  1570.  
  1571.                         3) Place the first letter it removed in step 1
  1572.                            onto the right tail end of the string, and
  1573.  
  1574.                         4) Center  the  string  on the display at  the
  1575.                            requested row.
  1576.  
  1577.                    Thus, the single call will shift the string by  one
  1578.                    character   and   redisplay  it.   To  see  how  to
  1579.                    implement the continuous scrolling effect, see  the
  1580.                    example below.
  1581.  
  1582.  
  1583.                    Example:  The  string we will use in our example is
  1584.                    called bannerString$, and we will display it on the
  1585.                    12th (middle) row of the screen.  This routine will
  1586.                    continue to  scroll  the  banner  until  a  key  is
  1587.                    pressed.
  1588.  
  1589.                    ' Banner example begins
  1590.                    bannerString$ = "The Marvelous Screen Routines"
  1591.                    DO
  1592.                        Banner bannerString$, 12
  1593.                    LOOP UNTIL INKEY$ <> ""
  1594.                    ' Banner example ends
  1595.  
  1596.  
  1597.  
  1598.  
  1599.  
  1600.  
  1601.                                                                page 23
  1602.  
  1603.  
  1604.  
  1605.                    Known Limitations: The Banner routine relies on the
  1606.                    STATIC statement at the end of its  declaration  to
  1607.                    maintain  its position in the string between calls.
  1608.                    This means  that  you  can  only  call  the  Banner
  1609.                    routine for one string per program.  If you want to
  1610.                    display  more than one banner in your program, or a
  1611.                    different banner with different text, this  routine
  1612.                    isn't for you.
  1613.  
  1614.  
  1615.  
  1616.  
  1617.  
  1618.  
  1619.  
  1620.  
  1621.  
  1622.  
  1623.  
  1624.  
  1625.  
  1626.  
  1627.  
  1628.  
  1629.  
  1630.  
  1631.  
  1632.  
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656.  
  1657.  
  1658.  
  1659.  
  1660.  
  1661.  
  1662.  
  1663.                                                                page 24
  1664.  
  1665.  
  1666.  
  1667.  
  1668.          Function BLOCKSIZE
  1669.          -------------------------------------------------------------
  1670.  
  1671.  
  1672.                    Purpose:   To  calculate  the  number  of  elements
  1673.                    required for an array that will be used to  save  a
  1674.                    rectangular   portion   of   the  screen,  via  the
  1675.                    BlockSave routine (below).
  1676.  
  1677.  
  1678.                    Usage: Right inside of a DIM statement, such as
  1679.  
  1680.                           DIM blockArray%(BlockSize%(l%, r%, t%, b%))
  1681.  
  1682.                              l% - left column of area to save
  1683.                              r% - right column of area to save
  1684.                              t% - top row of area to save
  1685.                              b% - bottom row of area to save
  1686.  
  1687.                    Details: This routine is  useful  when  saving  and
  1688.                    restoring  parts  of the screen using the BlockSave
  1689.                    and BlockRestore routines (below).  You  will  need
  1690.                    to  know  how  big to dimension the array that will
  1691.                    hold the screen information, and this function will
  1692.                    calculate the exact number  of  elements  required.
  1693.                    You  could  dimension  an array to 4000 elements to
  1694.                    cover all cases,  but  that  would  be  wasteful of
  1695.                    memory.  BlockSize makes your programs efficient.
  1696.  
  1697.                    To  use the function, you can assign its value to a
  1698.                    variable, and then use the variable as the argument
  1699.                    in your DIM statement, or you could  be  even  more
  1700.                    efficient and place the BlockSize function directly
  1701.                    into  your  DIM  statement,  as  shown above in the
  1702.                    Usage.  Simply fill in the parameters for the left,
  1703.                    right, top, and bottom  sides  of  the  rectangular
  1704.                    area you want to save, and BlockSize does the rest.
  1705.  
  1706.  
  1707.                    Example:   The  example  below  uses  BlockSize  to
  1708.                    dimension a variable  called  sArray%(),  and  then
  1709.                    calls  upon  BlockSave  to  save  the  area  of the
  1710.                    screen.
  1711.  
  1712.                    ' BlockSize example begins
  1713.                    ' Dimension an array to hold screen information
  1714.                    DIM sArray%(BlockSize%(1, 15, 1, 10))
  1715.  
  1716.                    ' Save the area of the screen
  1717.                    BlockSave 1, 15, 1, 10, sArray%(), GetVideoSegment
  1718.  
  1719.                    ' BlockSize example ends
  1720.  
  1721.  
  1722.                    Known Limitations: None.
  1723.  
  1724.  
  1725.                                                                page 25
  1726.  
  1727.  
  1728.  
  1729.  
  1730.          Subprogram BLOCKRESTORE
  1731.          -------------------------------------------------------------
  1732.  
  1733.  
  1734.                    Purpose: To restore a rectangular area of the video
  1735.                    display  that  was previously saved using BlockSave
  1736.                    (below).
  1737.  
  1738.  
  1739.                    Usage: BlockRestore l%, r%, t%, b%, scrArray%(),
  1740.                              segment!
  1741.  
  1742.                              l% - left column of area to restore
  1743.                              r% - right column of area to restore
  1744.                              t% - top row of area to restore
  1745.                              b% - bottom row of area to restore
  1746.                              scrArray%() - the array in  which  screen
  1747.                                            information was saved
  1748.                              segment! - the  memory   segment  of  the
  1749.                                         display   memory.    Use   the
  1750.                                         function  GetVideoSegment  for
  1751.                                         this
  1752.  
  1753.  
  1754.                    Details:  This  routine  is to be used to restore a
  1755.                    portion of the video display  that  has  previously
  1756.                    been  saved  using  the BlockSave function (below).
  1757.                    Once you have finished  with  the  portion  of  the
  1758.                    display  you  had  previously saved, make a call to
  1759.                    this routine and it will restore what was saved.
  1760.  
  1761.                    This   routine  is  essentially  a  more  efficient
  1762.                    version of the ScrnRestore routine,  also  part  of
  1763.                    the    QBSCR   Screen   Routines.    ScrnSave   and
  1764.                    ScrnRestore  are  provided   to   maintain   upward
  1765.                    compatibility  from previous versions of the Screen
  1766.                    Routines.  This should be the preferred routine  to
  1767.                    use  when  saving  and  restoring  PORTIONS  of the
  1768.                    screen.
  1769.  
  1770.                    Make sure when you call this routine that  you  use
  1771.                    the same coordinates that you used on the BlockSave
  1772.                    call,  or  you  will get a "Subscript Out of Range"
  1773.                    error at runtime.
  1774.  
  1775.                    For more information regarding the screen save  and
  1776.                    restore   process,  see  the  BlockSave  subprogram
  1777.                    below,  and  the  section  of  this  manual  titled
  1778.                    "Displaying and Popping a Window."
  1779.  
  1780.  
  1781.                    Example:  The  example  below  goes through all the
  1782.                    steps necessary to allocate (DIMension) an array in
  1783.                    which to save a portion of the screen, saving,  and
  1784.                    then restoring the display.
  1785.  
  1786.  
  1787.                                                                page 26
  1788.  
  1789.  
  1790.  
  1791.                    ' BlockRestore example begins
  1792.                    ' Dimension an array to hold the screen information
  1793.                    DIM s%(BlockSize%(1, 15, 1, 10))
  1794.  
  1795.                    ' Save the rectangular area of the screen
  1796.                    BlockSave 1, 15, 1, 10, s%(), GetVideoSegment
  1797.  
  1798.                    ' At this point you could overwrite the portion of
  1799.                    ' the display that was saved, with a window or
  1800.                    ' perhaps a menu.  Once you are finished with the
  1801.                    ' part of the display that was overwritten, you
  1802.                    ' would restore what was there in the first place,
  1803.                    ' like this:
  1804.  
  1805.                    ' Restore the saved portion of the display
  1806.                    BlockRestore 1, 15, 1, 10, s%(), GetVideoSegment
  1807.  
  1808.                    ' BlockRestore example ends
  1809.  
  1810.  
  1811.                    Known Limitations: None.
  1812.  
  1813.  
  1814.  
  1815.  
  1816.  
  1817.  
  1818.  
  1819.  
  1820.  
  1821.  
  1822.  
  1823.  
  1824.  
  1825.  
  1826.  
  1827.  
  1828.  
  1829.  
  1830.  
  1831.  
  1832.  
  1833.  
  1834.  
  1835.  
  1836.  
  1837.  
  1838.  
  1839.  
  1840.  
  1841.  
  1842.  
  1843.  
  1844.  
  1845.  
  1846.  
  1847.  
  1848.  
  1849.                                                                page 27
  1850.  
  1851.  
  1852.  
  1853.  
  1854.          Subprogram BLOCKSAVE
  1855.          -------------------------------------------------------------
  1856.  
  1857.  
  1858.                    Purpose:  To  save  a rectangular area of the video
  1859.                    display  so  that  it   may   be   restored   using
  1860.                    BlockRestore (above) after being overwritten.
  1861.  
  1862.  
  1863.                    Usage: BlockSave l%, r%, t%, b%, scrArray%(),
  1864.                              segment!
  1865.  
  1866.                              l% - left column of area to save
  1867.                              r% - right column of area to save
  1868.                              t% - top row of area to save
  1869.                              b% - bottom row of area to save
  1870.                              scrArray%() - the array in  which  screen
  1871.                                            information will be saved
  1872.                              segment! - the  memory   segment  of  the
  1873.                                         display   memory.    Use   the
  1874.                                         function  GetVideoSegment  for
  1875.                                         this
  1876.  
  1877.  
  1878.                    Details:  If  you need to display a window or other
  1879.                    information  on  top of your existing  display, you
  1880.                    can use BlockSave (and  subsequently  BlockRestore)
  1881.                    to  do it.  Just save the portion of the screen you
  1882.                    are going to be overwriting  with  BlockSave,  then
  1883.                    display  whatever you need in the saved area.  Once
  1884.                    you are done with the area, and need the  old  info
  1885.                    back  on-screen,  use  BlockRestore to get it back.
  1886.                    For more information on  this  technique,  see  the
  1887.                    section  of  this  manual  titled  "Displaying  and
  1888.                    Popping a Window."
  1889.  
  1890.                    This  routine  is  essentially  a  more   efficient
  1891.                    version  of  the ScrnSave routine, also part of the
  1892.                    QBSCR Screen Routines.   ScrnSave  and  ScrnRestore
  1893.                    are  provided to maintain upward compatibility from
  1894.                    previous versions of  the  Screen  Routines.   This
  1895.                    should  be the preferred routine to use when saving
  1896.                    and restoring PORTIONS of the screen.
  1897.  
  1898.                    Make sure when you call  the  BlockRestore  routine
  1899.                    that  you use the same coordinates that you used on
  1900.                    the BlockSave call, or you will  get  a  "Subscript
  1901.                    Out of Range" error at runtime.
  1902.  
  1903.  
  1904.                    Example:  The  example  below  goes through all the
  1905.                    steps necessary to allocate (DIMension) an array in
  1906.                    which to save a portion of the screen, saving,  and
  1907.                    then restoring the display.
  1908.  
  1909.  
  1910.  
  1911.                                                                page 28
  1912.  
  1913.                    ' BlockRestore example begins
  1914.                    ' Dimension an array to hold the screen information
  1915.                    DIM s%(BlockSize%(1, 15, 1, 10))
  1916.  
  1917.                    ' Save the rectangular area of the screen
  1918.                    BlockSave 1, 15, 1, 10, s%(), GetVideoSegment
  1919.  
  1920.                    ' At this point you could overwrite the portion of
  1921.                    ' the display that was saved, with a window or
  1922.                    ' perhaps a menu.  Once you are finished with the
  1923.                    ' part of the display that was overwritten, you
  1924.                    ' would restore what was there in the first place,
  1925.                    ' like this:
  1926.  
  1927.                    ' Restore the saved portion of the display
  1928.                    BlockRestore 1, 15, 1, 10, s%(), GetVideoSegment
  1929.  
  1930.                    ' BlockSave example ends
  1931.  
  1932.  
  1933.                    Known Limitations: None.
  1934.  
  1935.  
  1936.  
  1937.  
  1938.  
  1939.  
  1940.  
  1941.  
  1942.  
  1943.  
  1944.  
  1945.  
  1946.  
  1947.  
  1948.  
  1949.  
  1950.  
  1951.  
  1952.  
  1953.  
  1954.  
  1955.  
  1956.  
  1957.  
  1958.  
  1959.  
  1960.  
  1961.  
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.                                                                page 29
  1974.  
  1975.  
  1976.  
  1977.  
  1978.          Subprogram BUILDSCREEN
  1979.          -------------------------------------------------------------
  1980.  
  1981.  
  1982.                    Purpose:  To  place  a  predefined  display  on the
  1983.                    screen in an interesting fashion.
  1984.  
  1985.  
  1986.                    Usage: BuildScreen file$, mode%
  1987.  
  1988.                              file$  -  the  file  that  is the premade
  1989.                                      display to be put on the screen.
  1990.                              mode% - Specifies the manner in which the
  1991.                                      screen  is  to  be  placed on the
  1992.                                      display. Value  must  be  in  the
  1993.                                      range  0  through 15. See the REF
  1994.                                      program for  a  demonstration  of
  1995.                                      each mode%.
  1996.  
  1997.  
  1998.                    Details:  To  use BuildScreen, your premade display
  1999.                    must  have  been  created either with the GetScreen
  2000.                    routine or the Screen  Builder  program.   See  the
  2001.                    section of this manual entitled "The SCREEN BUILDER
  2002.                    Program,"  or  the Screen Builder documentation for
  2003.                    more information.
  2004.  
  2005.                    To  have  BuildScreen  display  one of your premade
  2006.                    screens, you must tell it
  2007.  
  2008.                         1. The file that contains the screen, and
  2009.                         2. The display mode to use when placing it
  2010.                            on the screen.
  2011.  
  2012.                    There are 16 different ways  that  BuildScreen  can
  2013.                    display  your  screen.  To see all of them, run the
  2014.                    REF  program  that  accompanies  this  package  and
  2015.                    select  the  BuildScreen  modes from the main menu.
  2016.                    Then follow the onscreen instructions.
  2017.  
  2018.                    This  routine  can  provide  some wonderful special
  2019.                    effects for your program.  The most  immediate  use
  2020.                    for BuildScreen I can see is for the opening screen
  2021.                    of  your  program.  You can just as easily generate
  2022.                    any kind of ASCII multicolor text display you need,
  2023.                    for data entry screens,  premade  windows  or  info
  2024.                    screens, or whatever.
  2025.  
  2026.  
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.                                                                page 30
  2036.  
  2037.  
  2038.  
  2039.                    Example: In the example below, we will  be  placing
  2040.                    on  the  screen  a premade display stored in a file
  2041.                    called DISPLAY.CLR.  The BuildScreen mode  will  be
  2042.                    15.
  2043.  
  2044.                    ' BuildScreen example begins
  2045.                    ' Assign a BuildScreen mode%
  2046.                    buildMode% = 15
  2047.  
  2048.                    ' Assign a filename
  2049.                    file$ = "DISPLAY.CLR"
  2050.  
  2051.                    ' Build the screen with BuildScreen
  2052.                    BuildScreen file$, buildMode%
  2053.  
  2054.                    ' BuildScreen example ends
  2055.  
  2056.  
  2057.                    Known Limitations: None.
  2058.  
  2059.  
  2060.  
  2061.  
  2062.  
  2063.  
  2064.  
  2065.  
  2066.  
  2067.  
  2068.  
  2069.  
  2070.  
  2071.  
  2072.  
  2073.  
  2074.  
  2075.  
  2076.  
  2077.  
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083.  
  2084.  
  2085.  
  2086.  
  2087.  
  2088.  
  2089.  
  2090.  
  2091.  
  2092.  
  2093.  
  2094.  
  2095.  
  2096.  
  2097.                                                                page 31
  2098.  
  2099.  
  2100.  
  2101.  
  2102.          Subprogram CENTER
  2103.          -------------------------------------------------------------
  2104.  
  2105.  
  2106.                    Purpose:  To  center any string of text in a row of
  2107.                    the screen specified by the programmer.
  2108.  
  2109.  
  2110.                    Usage: Center st$, row%
  2111.  
  2112.                              st$  - The string to center on the screen
  2113.                              row% - The row of the  screen  to  center
  2114.                                     the text on.  Must be from 1 to 25
  2115.  
  2116.  
  2117.                    Details:  This routine is very simple to use.  Tell
  2118.                    it the string you want to center on the screen  and
  2119.                    the  row  of the screen you want it on.  The string
  2120.                    must be less than or  equal  to  80  characters  in
  2121.                    length.
  2122.  
  2123.  
  2124.                    Example:   This  example  is very straight-forward.
  2125.                    It will center the string provided to  the  routine
  2126.                    call  as  a literal string (not a variable), on the
  2127.                    row specified (in this case, row 3).
  2128.  
  2129.                    ' Center example 1 begins
  2130.                    Center "A string to center on the screen", 3
  2131.                    ' Center example 1 ends
  2132.  
  2133.                    You could also use variables if you like, as in the
  2134.                    example 2 below:
  2135.  
  2136.                    ' Center example 2 begins
  2137.                    string$ = "A string to center on the screen"
  2138.                    row% = 3
  2139.                    Center string$, row%
  2140.                    ' Center example 2 ends
  2141.  
  2142.  
  2143.                    Known Limitations: None.
  2144.  
  2145.  
  2146.  
  2147.  
  2148.  
  2149.  
  2150.  
  2151.  
  2152.  
  2153.  
  2154.  
  2155.  
  2156.  
  2157.  
  2158.  
  2159.                                                                page 32
  2160.  
  2161.  
  2162.  
  2163.  
  2164.          Subprogram CLRSCR
  2165.          -------------------------------------------------------------
  2166.  
  2167.  
  2168.                    Purpose: To clear the display screen in interesting
  2169.                    ways.
  2170.  
  2171.  
  2172.                    Usage: ClrScr mode%, fillchar$
  2173.  
  2174.                              mode%     - Specifies the manner in which
  2175.                                          the  display is cleared.  Has
  2176.                                          16 predefined  modes.   Value
  2177.                                          must be in the range 0 - 15.
  2178.                              fillchar$ - The  character to  clear  the
  2179.                                          screen with.  Will usually be
  2180.                                          a space.
  2181.  
  2182.  
  2183.                    Details: The ClrScr  routine  provides  interesting
  2184.                    ways  of  clearing  the screen inside your program.
  2185.                    One thing to remember is that if you want to  clear
  2186.                    the  screen  so  that  it  is black, set the screen
  2187.                    colors to something with a black background  BEFORE
  2188.                    calling  ClrScr.   It  assumes  that  you  have the
  2189.                    colors set how you want them.  For a  demonstration
  2190.                    of all the ClrScr modes, run the REF program.
  2191.  
  2192.                    Note  also  that the ClrScr modes correspond to the
  2193.                    BuildScreen modes.
  2194.  
  2195.  
  2196.                    Example:  The  following  example  will  clear  the
  2197.                    display screen using ClrScr mode 15.
  2198.  
  2199.                    ' ClrScr example begins
  2200.                    clrMode% = 15
  2201.                    fill$ = " "
  2202.                    ClrScr clrMode%, fill$
  2203.                    ' ClrScr example ends
  2204.  
  2205.  
  2206.                    Known  Limitations:  ClrScr  mode  15 is a tad slow
  2207.                    toward the end of the clear sequence.
  2208.  
  2209.  
  2210.  
  2211.  
  2212.  
  2213.  
  2214.  
  2215.  
  2216.  
  2217.  
  2218.  
  2219.  
  2220.  
  2221.                                                                page 33
  2222.  
  2223.  
  2224.  
  2225.  
  2226.          Function COLORCHK
  2227.          -------------------------------------------------------------
  2228.  
  2229.  
  2230.                    Purpose: To determine if the host machine has color
  2231.                    display capability.
  2232.  
  2233.  
  2234.                    Usage: As a function that returns a true  or  false
  2235.                    value  in  a  logical  expression.  See example for
  2236.                    more information.
  2237.  
  2238.  
  2239.                    Details: The COLORCHK function will return a  value
  2240.                    of TRUE (non-zero) if the machine it is executed on
  2241.                    has  the  capability  to  display  color.   It will
  2242.                    return FALSE (zero) if the  machine  is  monochrome
  2243.                    only.   Use it in a logical expression to determine
  2244.                    the colors you should use in your program.
  2245.  
  2246.  
  2247.                    Example: The example below demonstrates  the  usage
  2248.                    of  COLORCHK  to  set  the colors before displaying
  2249.                    some text.  Once it is known  whether  or  not  the
  2250.                    machine  can  display color, you can set the colors
  2251.                    appropriately.
  2252.  
  2253.                    ' ColorChk example begins
  2254.                    IF ColorChk THEN
  2255.                        COLOR 14, 4  'Yellow on Red -ColorChk is TRUE
  2256.                    ELSE
  2257.                        COLOR 7, 0   'White on Black -ColorChk is FALSE
  2258.                    END IF
  2259.                    PRINT "This text will be in the right color."
  2260.                    ' ColorChk example ends
  2261.  
  2262.  
  2263.                    Known Limitations: The function will determine only
  2264.                    if  color  capability  is  available.   It will not
  2265.                    determine the specific graphics adapter  installed.
  2266.  
  2267.  
  2268.  
  2269.  
  2270.  
  2271.  
  2272.  
  2273.  
  2274.  
  2275.  
  2276.  
  2277.  
  2278.  
  2279.  
  2280.  
  2281.  
  2282.  
  2283.                                                                page 34
  2284.  
  2285.  
  2286.  
  2287.  
  2288.          Function GETBACKGROUND
  2289.          -------------------------------------------------------------
  2290.  
  2291.  
  2292.                    Purpose:  To  determine the background color of any
  2293.                    specified location on the display screen.
  2294.  
  2295.  
  2296.                    Usage: As a function that returns an integer  value
  2297.                    that is a valid BASIC background color (0-7).
  2298.  
  2299.                          background% = GetBackground%(row%, col%)
  2300.  
  2301.                              row%  - the row portion of the coordinate
  2302.                                      to return a background value for
  2303.                              col%  - the   column   portion   of   the
  2304.                                      coordinate to return a background
  2305.                                      value for
  2306.  
  2307.  
  2308.                    Details: If you need to know the  background  color
  2309.                    of  any  character on the screen, use this function
  2310.                    to  obtain  it.   Used  in  combination  with   the
  2311.                    GetForeground  function, the complete colors of any
  2312.                    spot on the screen can be determined.
  2313.  
  2314.                    The  row  and  column  parameters are passed to the
  2315.                    function to tell it exactly which  screen  location
  2316.                    for  which  you want the background color.  It will
  2317.                    return  a  value  from  0  to  7,  indicating   the
  2318.                    background color of the specified character cell.
  2319.  
  2320.  
  2321.                    Example:  The  example  below   will   obtain   the
  2322.                    background  color for the character cell at row 10,
  2323.                    column 20.
  2324.  
  2325.                    ' GetBackground example begins
  2326.                    ' Assign the background color to the variable
  2327.                    ' called background%
  2328.                    background% = GetBackground (10, 20)
  2329.  
  2330.                    ' GetBackground example ends
  2331.  
  2332.  
  2333.                    Known Limitations: None.
  2334.  
  2335.  
  2336.  
  2337.  
  2338.  
  2339.  
  2340.  
  2341.  
  2342.  
  2343.  
  2344.  
  2345.                                                                page 35
  2346.  
  2347.  
  2348.  
  2349.  
  2350.          Function GETFOREGROUND
  2351.          -------------------------------------------------------------
  2352.  
  2353.  
  2354.                    Purpose:  To  determine the foreground color of any
  2355.                    specified location on the display screen.
  2356.  
  2357.  
  2358.                    Usage: As a function that returns an integer  value
  2359.                    that is a valid BASIC foreground color (0-31).
  2360.  
  2361.                          foreground% = GetForeground%(row%, col%)
  2362.  
  2363.                              row%  - the row portion of the coordinate
  2364.                                      to return a foreground value for
  2365.                              col%  - the   column   portion   of   the
  2366.                                      coordinate to return a foreground
  2367.                                      value for
  2368.  
  2369.  
  2370.                    Details:  If  you need to know the foreground color
  2371.                    of any character on the screen, use  this  function
  2372.                    to   obtain  it.   Used  in  combination  with  the
  2373.                    GetBackground function, the complete colors of  any
  2374.                    spot on the screen can be determined.
  2375.  
  2376.                    The row and column parameters  are  passed  to  the
  2377.                    function  to  tell it exactly which screen location
  2378.                    for which you want the foreground color.   It  will
  2379.                    return  a  value  from  0  to  31,  indicating  the
  2380.                    foreground color of the specified character cell.
  2381.  
  2382.  
  2383.                    Example:   The   example   below  will  obtain  the
  2384.                    foreground and background colors for the  character
  2385.                    cell at row 10, column 20.
  2386.  
  2387.                    ' GetForeground example begins
  2388.                    ' Assign the foreground and background color to the
  2389.                    ' variables called foreground% and background%
  2390.                    foreground% = GetForeground (10, 20)
  2391.                    background% = GetBackground (10, 20)
  2392.  
  2393.                    ' GetForeground example ends
  2394.  
  2395.  
  2396.                    Known Limitations: None.
  2397.  
  2398.  
  2399.  
  2400.  
  2401.  
  2402.  
  2403.  
  2404.  
  2405.  
  2406.  
  2407.                                                                page 36
  2408.  
  2409.  
  2410.  
  2411.  
  2412.          Subprogram GETSCREEN
  2413.          -------------------------------------------------------------
  2414.  
  2415.  
  2416.                    Purpose:  Will  save  the  contents  of  the screen
  2417.                    display to a disk file.
  2418.  
  2419.  
  2420.                    Usage: GetScreen file$
  2421.  
  2422.                              file$ - the file  in  which  the  display
  2423.                                      contents will be saved.
  2424.  
  2425.  
  2426.                    Details: This routine will save the contents of the
  2427.                    video display to a disk file.  While there probably
  2428.                    won't be much call for this routine, it can be used
  2429.                    whenever  a  screen capture capability is required.
  2430.                    Note that this routine is the heart of  the  Screen
  2431.                    Builder's Save function.
  2432.  
  2433.  
  2434.                    Example: This example will save the contents of the
  2435.                    display to a disk file called SAVED.SCR.
  2436.  
  2437.                    ' GetScreen example begins
  2438.                    ' Save display contents to a file
  2439.                    GetScreen "SAVED.SCR"
  2440.  
  2441.                    ' GetScreen example ends
  2442.  
  2443.  
  2444.                    Known  Limitations:  Will  save  screen information
  2445.                    only in the binary BASIC format.
  2446.  
  2447.  
  2448.  
  2449.  
  2450.  
  2451.  
  2452.  
  2453.  
  2454.  
  2455.  
  2456.  
  2457.  
  2458.  
  2459.  
  2460.  
  2461.  
  2462.  
  2463.  
  2464.  
  2465.  
  2466.  
  2467.  
  2468.  
  2469.                                                                page 37
  2470.  
  2471.  
  2472.  
  2473.  
  2474.          Function GETSTRING
  2475.          -------------------------------------------------------------
  2476.  
  2477.  
  2478.                    Purpose: To obtain string input from the user while
  2479.                    limiting the length of the string the  user  enters
  2480.                    as they enter it.
  2481.  
  2482.  
  2483.                    Usage: st$ = GetString$(lCol, row%, lngth%, f%, b%)
  2484.  
  2485.                              st$    - Any variable name to  which  the
  2486.                                       user's entry  will  be  assigned
  2487.                                       when they have completed entry.
  2488.                              lCol   - The  left-most column  to  begin
  2489.                                       begin  displaying   the   user's
  2490.                                       entry on as they type.
  2491.                              row%   - The row of the screen to display
  2492.                                       the  user's  entry  on  as  they
  2493.                                       type.
  2494.                              lngth% - The maximum length of the string
  2495.                                       the user is allowed to enter.
  2496.                              f%     - The foreground color in which to
  2497.                                       display the user's entry.
  2498.                              b%     - The background color in which to
  2499.                                       display the user's entry.
  2500.  
  2501.  
  2502.                    Details: While the user is typing in an entry, they
  2503.                    may use the backspace key to correct errors.   Once
  2504.                    the  user  has  finished  entering characters, they
  2505.                    will hit the ENTER key to  signify  that  they  are
  2506.                    finished.  If the user hits the ESC key, then ASCII
  2507.                    27  (Escape)  will  be  immediately returned by the
  2508.                    GetString function.   You  can  test  for  the  ESC
  2509.                    character  and act as you see fit.  Try hitting the
  2510.                    ESC key in the DEMO program, or look  at  the  DEMO
  2511.                    source code to see how it handles the ESC key.
  2512.  
  2513.                    You  can  easily  modify  the  source code for this
  2514.                    function  to  limit  the  characters  the  user  is
  2515.                    allowed  to  enter.   The current range is ASCII 32
  2516.                    through 254.  Simply change the line  in  the  CASE
  2517.                    statement  in  the  source code to suit your needs.
  2518.                    For example, if you wanted  the  user  to  only  be
  2519.                    allowed to enter numbers, you could change the case
  2520.                    statement to read
  2521.  
  2522.                                      CASE "0" TO "9"
  2523.  
  2524.                    and  the  CASE  ELSE  will  take care of extraneous
  2525.                    illegal input.
  2526.  
  2527.  
  2528.  
  2529.  
  2530.  
  2531.                                                                page 38
  2532.  
  2533.  
  2534.                    Example:  This  example  will  use  the   GetString
  2535.                    function to accept an eight-character filename from
  2536.                    the  user.  If the user hits the ESC key, a message
  2537.                    will be printed and  the  example  will  end.   The
  2538.                    entry will be at the 10th column of row 5, and will
  2539.                    be in reverse video (Black on White).
  2540.  
  2541.                    ' GetString example begins
  2542.                    CONST FALSE = 0, TRUE = NOT FALSE
  2543.  
  2544.                    lCol% = 10: row% = 5
  2545.                    entryOK = FALSE
  2546.                    DO
  2547.                        st$ = GetString$(lCol%, row%, 8, 0, 7)
  2548.                        SELECT CASE st$
  2549.                        CASE CHR$(27)  ' The ESC key
  2550.                            LOCATE 6, 10
  2551.                            PRINT "User hit ESC!"
  2552.                            entryOK = TRUE
  2553.                        CASE ""        ' User simply hit ENTER
  2554.                            LOCATE 6, 10
  2555.                            PRINT "Try that again..."
  2556.                        CASE ELSE      ' Assume correct entry
  2557.                            entryOK = TRUE
  2558.                        END SELECT
  2559.                    LOOP UNTIL entryOK
  2560.                    ' GetString example ends
  2561.  
  2562.  
  2563.                    Known Limitations: The only editing key provided is
  2564.                    the  backspace  key.   Future versions of the QBSCR
  2565.                    will add more editing keys, like  Home,  End,  etc.
  2566.                    Feel free to add your own.
  2567.  
  2568.  
  2569.  
  2570.  
  2571.  
  2572.  
  2573.  
  2574.  
  2575.  
  2576.  
  2577.  
  2578.  
  2579.  
  2580.  
  2581.  
  2582.  
  2583.  
  2584.  
  2585.  
  2586.  
  2587.  
  2588.  
  2589.  
  2590.  
  2591.  
  2592.  
  2593.                                                                page 39
  2594.  
  2595.  
  2596.  
  2597.  
  2598.          Function GETVIDEOSEGMENT
  2599.          -------------------------------------------------------------
  2600.  
  2601.  
  2602.                    Purpose:  Returns  the proper memory address of the
  2603.                    video card display memory.  Used with the  SCRNSAVE
  2604.                    and   SCRNRESTORE   routines,   the  BLOCKSAVE  and
  2605.                    BLOCKRESTORE routines, and internally  by  some  of
  2606.                    the routines.
  2607.  
  2608.  
  2609.                    Usage: segment = GetVideoSegment
  2610.                           - or as part of an expression  or  parameter
  2611.                             list.  See example below.
  2612.  
  2613.  
  2614.                    Details: This function is used  primarily  for  the
  2615.                    SCRNSAVE   and   SCRNRESTORE  (also  BlockSave  and
  2616.                    BlockRestore) functions.   These  routines  require
  2617.                    knowledge  of  the  location  of  the video display
  2618.                    card's memory.  This function provides it.   It  is
  2619.                    necessary  because  the  display  memory  for color
  2620.                    video starts at an address different from  that  of
  2621.                    monochrome video.
  2622.  
  2623.                    There are two ways to use this function.   You  may
  2624.                    either  assign  the  result  of  this function to a
  2625.                    variable, as in the usage above, or you  can  place
  2626.                    the  function  name  directly  in  the SCRNSAVE and
  2627.                    SCRNRESTORE  (also  BlockSave   and   BlockRestore)
  2628.                    function  parameter  list.  The examples below will
  2629.                    demonstrate both usages.   The  first  method  will
  2630.                    result   in   slightly  faster  execution  of  your
  2631.                    program, yet requires  the  use  of  an  additional
  2632.                    variable.  The second method is easier and does not
  2633.                    require  the  use of a second variable, but may run
  2634.                    slower, since the function will be evaluated  every
  2635.                    time it is used.
  2636.  
  2637.  
  2638.                    Example:  The  following  examples will demonstrate
  2639.                    the same thing - using GETVIDEOSEGMENT  to  provide
  2640.                    information to the SCRNSAVE routine.  It is assumed
  2641.                    that  the  array  scrArray%()  has  been  allocated
  2642.                    (DIMensioned) already.
  2643.  
  2644.                    ' GetVideoSegment example 1 begins
  2645.                    segment = GetVideoSegment
  2646.                    ScrnSave 1, 25, scrArray()%, segment
  2647.                    ' GetVideoSegment example 1 ends
  2648.  
  2649.  
  2650.  
  2651.  
  2652.  
  2653.  
  2654.  
  2655.                                                                page 40
  2656.  
  2657.  
  2658.  
  2659.                    ' GetVideoSegment example 2 begins
  2660.                    ScrnSave 1, 25, scrArray()%, GetVideoSegment
  2661.                    ' GetVideoSegment example 2 ends
  2662.  
  2663.  
  2664.                    Known Limitations: None.
  2665.  
  2666.  
  2667.  
  2668.  
  2669.  
  2670.  
  2671.  
  2672.  
  2673.  
  2674.  
  2675.  
  2676.  
  2677.  
  2678.  
  2679.  
  2680.  
  2681.  
  2682.  
  2683.  
  2684.  
  2685.  
  2686.  
  2687.  
  2688.  
  2689.  
  2690.  
  2691.  
  2692.  
  2693.  
  2694.  
  2695.  
  2696.  
  2697.  
  2698.  
  2699.  
  2700.  
  2701.  
  2702.  
  2703.  
  2704.  
  2705.  
  2706.  
  2707.  
  2708.  
  2709.  
  2710.  
  2711.  
  2712.  
  2713.  
  2714.  
  2715.  
  2716.  
  2717.                                                                page 41
  2718.  
  2719.  
  2720.  
  2721.  
  2722.          Function MAKEMENU
  2723.          -------------------------------------------------------------
  2724.  
  2725.  
  2726.                    Purpose: To produce a menu on the screen and return
  2727.                    a user's selection.
  2728.  
  2729.  
  2730.                    Usage: s% = MakeMenu%(choices$(), numOfChoices%,
  2731.                                          justify$, leftCol, rightCol,
  2732.                                          row%, marker$,
  2733.                                          fg%, bg%, hfg%, hbg%,
  2734.                                          qfg%, qbg%)
  2735.  
  2736.                                s% - Any  integer  variable  that  will
  2737.                                     hold the number of the user's menu
  2738.                                     selection.
  2739.                                choices$() - An array of  strings  that
  2740.                                     are the choices to be displayed in
  2741.                                     the menu list.
  2742.                                numOfChoices%  -  The number of choices
  2743.                                     available in the menu.
  2744.                                justify$ - A single letter (L, R, or C)
  2745.                                     indicating   the   type   of  text
  2746.                                     justification to use when  placing
  2747.                                     the  menu  entries  on the screen.
  2748.                                     L = Left, R = Right, C = Centered.
  2749.                                leftCol%  -  The  left-most  column  to
  2750.                                     consider  when  placing  the  menu
  2751.                                     entries on the screen.
  2752.                                rightCol%  -  The  right-most column to
  2753.                                     consider  when  placing  the  menu
  2754.                                     entries on the screen.
  2755.                                row%  -  The first row of the screen to
  2756.                                     begin placing menu entries on.
  2757.                                marker$ - The character  used  to  tell
  2758.                                     MakeMenu  that  the next character
  2759.                                     in the entry is a Quick Access key
  2760.                                fg% - The foreground  color  of  normal
  2761.                                     menu entries.
  2762.                                bg%  -  The  background color of normal
  2763.                                     menu entries.
  2764.                                hfg% - The foreground color of  a  menu
  2765.                                     entry highlighted by the selection
  2766.                                     bar.
  2767.                                hbg%  -  The background color of a menu
  2768.                                     entry highlighted by the selection
  2769.                                     bar.
  2770.                                qfg% - The foreground color of  a  menu
  2771.                                     entry's "Quick Access" key.
  2772.                                qbg%  -  The background color of a menu
  2773.                                     entry's "Quick Access" key.
  2774.  
  2775.  
  2776.  
  2777.  
  2778.  
  2779.                                                                page 42
  2780.  
  2781.  
  2782.                    Details:  The  MakeMenu function will create on the
  2783.                    screen a vertical list of choices.   The  user  may
  2784.                    select one of the entries, the number of which will
  2785.                    be returned by the function.
  2786.  
  2787.                    The user has two mechanisms available to select one
  2788.                    of  the  menu  entries.  The first is the selection
  2789.                    bar.  This is a colored bar that moves  from  entry
  2790.                    to  entry  via  the  arrow  and  related keys.  The
  2791.                    following table describes the actions possible with
  2792.                    the selection bar  in  the  menu,  and  which  keys
  2793.                    perform these actions:
  2794.  
  2795.                    Menu Action...                   ...is Performed By
  2796.                    ---------------------------------------------------
  2797.                    Move selection bar DOWN 1 entry          Down Arrow
  2798.                    Move selection bar UP 1 entry              Up Arrow
  2799.                    Move selection bar to top of list        PgUp, Home
  2800.                    Move selection bar to bottom of list      PgDn, End
  2801.                    Select the currently highlighted entry        ENTER
  2802.                    Abort menu selection process                    ESC
  2803.  
  2804.                    There is a second mechanism available to  the  user
  2805.                    if  you  choose to implement it in your menu.  This
  2806.                    is the use of "Quick Access" keys.  A Quick  Access
  2807.                    key  is  a  single unique letter of each menu entry
  2808.                    that can be used to immediately select that  entry.
  2809.                    If  you  had  a  menu  entry called Quit, you could
  2810.                    specify the Q as a Quick Access key.  In this  way,
  2811.                    the  user  could hit the Q key to quit immediately,
  2812.                    instead of having to move the selection bar to  the
  2813.                    Quit entry and press ENTER.  Implementing the Quick
  2814.                    Access keys in your own menus is extremely simple.
  2815.  
  2816.                    To make the process of creating a menu more  clear,
  2817.                    let's step through the process of setting one up.
  2818.  
  2819.                    All the text of the menu entries is  stored  in  an
  2820.                    array.  You must dimension an array with the number
  2821.                    of entries in your menu, as in this example:
  2822.  
  2823.                                  numOfChoices% = 4
  2824.                                  DIM choices$(numOfChoices%)
  2825.  
  2826.                    This  would  allow  us  four  menu entries, or four
  2827.                    selections  available  to  the user.  The next step
  2828.                    would be to assign the text to each element of  the
  2829.                    array, as in the following hypothetical example:
  2830.  
  2831.                                 choices$(1) = "Load File"
  2832.                                 choices$(2) = "Edit File"
  2833.                                 choices$(3) = "Save File"
  2834.                                 choices$(4) = "Quit"
  2835.  
  2836.                    At  this  point you may choose to implement the use
  2837.                    of the Quick  Access  keys.   Simply  decide  which
  2838.                    letter  in each entry will be your Quick Access key
  2839.  
  2840.  
  2841.                                                                page 43
  2842.  
  2843.  
  2844.  
  2845.                    for that entry.  Each letter must  be  unique.   In
  2846.                    our  above  example, since the first letter in each
  2847.                    entry is unique, we can use  the  first  letter  of
  2848.                    each  entry  as my Quick Access key for that entry.
  2849.                    The  trick  is,  how  do  we  tell  MakeMenu  which
  2850.                    character  to  use?   This  is  where  the  marker$
  2851.                    parameter  comes  in.  Select  an  obscure   unused
  2852.                    character  (I  always use the ^ character) and pass
  2853.                    it to MakeMenu in the right  place.   Then,  simply
  2854.                    imbed  this  marker  character  (in  our case the ^
  2855.                    character) right BEFORE the letter you want to  use
  2856.                    as the Quick Access key. Below are our menu entries
  2857.                    redone to implement Quick Access keys:
  2858.  
  2859.                                 marker$ = "^"
  2860.                                 choices$(1) = "^Load File"
  2861.                                 choices$(2) = "^Edit File"
  2862.                                 choices$(3) = "^Save File"
  2863.                                 choices$(4) = "^Quit"
  2864.  
  2865.                    This  would allow the user to hit the L key to Load
  2866.                    a file, the E key to Edit a file, the S key to Save
  2867.                    a file, and the Q key to Quit.  Since  the  letters
  2868.                    L,  E,  S,  and  Q are unique, we are all set.  The
  2869.                    MakeMenu function takes care of  all  the  details.
  2870.                    All you had to do was tell it which letters to use.
  2871.                    When  the menu entries are displayed on the screen,
  2872.                    the Quick Access keys  will  be  highlighted  in  a
  2873.                    different  color  (the color specified by the qfg%,
  2874.                    and qbg% parameters you passed  to  MakeMenu).   If
  2875.                    you  don't want to implement the Quick Access keys,
  2876.                    simply do not imbed  any  marker  characters.  Make
  2877.                    sure  you  pass  an  unused  marker$  character  to
  2878.                    MakeMenu, though.
  2879.  
  2880.                    The next step would  be  to  decide  what  type  of
  2881.                    justification to use when the entries are displayed
  2882.                    on  the  screen.   You  may  use  left,  right,  or
  2883.                    centered  justification.   The  placement  will  be
  2884.                    relative  to the left and right columns you send to
  2885.                    MakeMenu.  Tell MakeMenu what type of justification
  2886.                    to use via the justify$ parameter.   This  variable
  2887.                    holds  a  single  letter, either an L, R, or C, for
  2888.                    Left, Right, or  Centered,  respectively.   In  our
  2889.                    example  we  will  use  Left  justification, so our
  2890.                    justify$ parameter will be L, as below:
  2891.  
  2892.                                      justify$ = "L"
  2893.  
  2894.                    Now you must decide where on the  screen  you  want
  2895.                    your  menu.   We will center our menu in the middle
  2896.                    of the screen.  The first row to begin placing  the
  2897.                    menu  entries on would be 11.  The left-most column
  2898.                    that would result in our entries being  roughly  in
  2899.                    the   middle   of  the  screen  is  36,  while  the
  2900.  
  2901.  
  2902.  
  2903.                                                                page 44
  2904.  
  2905.  
  2906.  
  2907.                    right-most column would be 45.  Set our  parameters
  2908.                    row%,  leftCol,  and rightCol to these values, like
  2909.                    this:
  2910.  
  2911.                                      row% = 11
  2912.                                      leftCol = 36
  2913.                                      rightCol = 45
  2914.  
  2915.                    The last step in preparing the menu is to decide on
  2916.                    the colors in which to display the menu.  There are
  2917.                    three parts to the menu, each of which must have  a
  2918.                    foreground and a background color:
  2919.  
  2920.                                    Normal Menu Entries
  2921.                                  The Selection Bar Entry
  2922.                                     Quick Access Keys
  2923.  
  2924.                    Lets assume we are working on a monochrome  display
  2925.                    and assign our colors accordingly (use the COLORCHK
  2926.                    function  listed  above  to  determine what kind of
  2927.                    display on which  the  program  is  running).   Our
  2928.                    normal   entries   will  be  white  on  black,  the
  2929.                    selection  bar  entries  will  be  black  on  white
  2930.                    (reverse  video),  and the Quick Access key letters
  2931.                    will be bright white on  black.   Here's  what  our
  2932.                    parameter assignments will look like:
  2933.  
  2934.                                 fg% = 7    ' White foreground
  2935.                                 bg% = 0    ' Black background
  2936.                                 hfg% = 0   ' Black foreground
  2937.                                 hbg% = 7   ' White background
  2938.                                 qfg% = 15  ' Bright White foreground
  2939.                                 qbg% = 0   ' Black background
  2940.  
  2941.                    The last step is to  make  the  call  to  MakeMenu.
  2942.                    Since MakeMenu is a function, you can place it in a
  2943.                    SELECT  CASE  statement,  or  any other expression.
  2944.                    Here will simply  assign  the  result  (the  user's
  2945.                    choice) to the variable s%:
  2946.  
  2947.                        s% = MakeMenu%(choices$(), numOfChoices%,
  2948.                                       justify$, leftCol, rightCol,
  2949.                                       row%, marker$,
  2950.                                       fg%, bg%, hfg%, hbg%,
  2951.                                       qfg%, qbg%)
  2952.  
  2953.                    Note  that  the  statement  would be contained on a
  2954.                    single  line  inside  your  program.   This   would
  2955.                    return the number of the entry the user selected in
  2956.                    the  list.  For example, if the user selected "Save
  2957.                    File,"  the third entry in our list, MakeMenu would
  2958.                    return a value of 3, and place it into the variable
  2959.                    s%.  You could then make your program act based  on
  2960.                    the user's selection returned by MakeMenu.
  2961.  
  2962.  
  2963.  
  2964.  
  2965.                                                                page 45
  2966.  
  2967.  
  2968.  
  2969.                    Example:  This  example  will  be in two parts. The
  2970.                    first example will reiterate the  example  used  in
  2971.                    the  Details  above,  but  in one contiguous piece.
  2972.                    The second example will show the same example using
  2973.                    literal parameters (the "shorthand" method).
  2974.  
  2975.                    ' MakeMenu example 1 begins
  2976.                    ' Dimension our array to hold menu choices
  2977.                    numOfChoices% = 4
  2978.                    DIM choices$(numOfChoices%)
  2979.  
  2980.                    ' Assign menu entries and set Quick Access keys
  2981.                    marker$ = "^"
  2982.                    choices$(1) = "^Load File"
  2983.                    choices$(2) = "^Edit File"
  2984.                    choices$(3) = "^Save File"
  2985.                    choices$(4) = "^Quit"
  2986.  
  2987.                    ' Set justification type and screen location
  2988.                    justify$ = "L"
  2989.                    row% = 11
  2990.                    leftCol = 36
  2991.                    rightCol = 45
  2992.  
  2993.                    ' Set colors for our menu
  2994.                    fg% = 7    ' White foreground
  2995.                    bg% = 0    ' Black background
  2996.                    hfg% = 0   ' Black foreground
  2997.                    hbg% = 7   ' White background
  2998.                    qfg% = 15  ' Bright White foreground
  2999.                    qbg% = 0   ' Black background
  3000.  
  3001.                    ' Make the Menu and get user's response
  3002.                    s% = MakeMenu%(choices$(), numOfChoices%,
  3003.                                   justify$, leftCol, rightCol,
  3004.                                   row%, marker$,
  3005.                                   fg%, bg%, hfg%, hbg%,
  3006.                                   qfg%, qbg%)
  3007.  
  3008.                    ' You could now act based on user's choice
  3009.                    ' MakeMenu example 1 ends
  3010.  
  3011.                    This  second   version   of   the   above   example
  3012.                    illustrates  how we don't have to use variables for
  3013.                    everything,  but  can  instead  use  actual  values
  3014.                    (literals).   In  this case, it's much shorter, but
  3015.                    does exactly the same thing.
  3016.  
  3017.                    ' MakeMenu example 2 begins
  3018.                    ' Dimension our array to hold menu choices
  3019.                    DIM choices$(4)
  3020.  
  3021.                    ' Assign menu entries and set Quick Access keys
  3022.                    choices$(1) = "^Load File"
  3023.                    choices$(2) = "^Edit File"
  3024.                    choices$(3) = "^Save File"
  3025.                    choices$(4) = "^Quit"
  3026.  
  3027.                                                                page 46
  3028.  
  3029.  
  3030.  
  3031.                    ' Make the menu and get user's response
  3032.                    s% = MakeMenu%(choices$(), 4, "C", 36, 45, 11,
  3033.                                   "^", 7, 0, 0, 7, 15, 0)
  3034.                    ' MakeMenu example 2 ends
  3035.  
  3036.                    Note that the actual MakeMenu call above  would  be
  3037.                    contained  on  a  single  line inside your program.
  3038.                    This method is easier to code, but  more  difficult
  3039.                    to understand if you come back to it a month later.
  3040.  
  3041.  
  3042.                    Known  Limitations: The menu must have at least two
  3043.                    entries but not more than 25.  Entry text  must  be
  3044.                    less  than  78  characters.   If  the selection bar
  3045.                    isn't lining up quite  right,  change  either  your
  3046.                    left  column  or  right  column  parameter  by one.
  3047.                    Fiddle with them a bit to make  the  selection  bar
  3048.                    symmetrical.
  3049.  
  3050.  
  3051.  
  3052.  
  3053.  
  3054.  
  3055.  
  3056.  
  3057.  
  3058.  
  3059.  
  3060.  
  3061.  
  3062.  
  3063.  
  3064.  
  3065.  
  3066.  
  3067.  
  3068.  
  3069.  
  3070.  
  3071.  
  3072.  
  3073.  
  3074.  
  3075.  
  3076.  
  3077.  
  3078.  
  3079.  
  3080.  
  3081.  
  3082.  
  3083.  
  3084.  
  3085.  
  3086.  
  3087.  
  3088.  
  3089.                                                                page 47
  3090.  
  3091.  
  3092.  
  3093.  
  3094.          Subprogram MAKEWINDOW
  3095.          -------------------------------------------------------------
  3096.  
  3097.  
  3098.                    Purpose:  To  make  windows on the screen, together
  3099.                    with supporting special effects.
  3100.  
  3101.  
  3102.                    Usage: MakeWindow topRow, leftCol, botRow,
  3103.                                      rightCol, foreColor%, backColor%,
  3104.                                      windowType%, frameType%,
  3105.                                      shadowColor%, explodeType%,
  3106.                                      label$
  3107.  
  3108.                              topRow - The top-most row of the window.
  3109.                              leftCol  -  The  left-most  column of the
  3110.                                      window.
  3111.                              botRow  -  The  bottom-most  row  of  the
  3112.                                      window.
  3113.                              rightCol  -  The right-most column of the
  3114.                                      window.
  3115.                              foreColor% - The foreground color of  the
  3116.                                      window.
  3117.                              backColor%  - The background color of the
  3118.                                      window.
  3119.                              windowType% - The type of window to make.
  3120.                                      See below for details.
  3121.                              frameType%  -  The  type  of  frame  from
  3122.                                      which to make  the  window  from.
  3123.                                      See below for details.
  3124.                              shadowColor% - The color of the  window's
  3125.                                      shadow.
  3126.                              explodeType%  -  Indicates how the window
  3127.                                      will be drawn on the screen.  See
  3128.                                      below for more information.
  3129.                              label$ - A text label for the window,  if
  3130.                                      desired.
  3131.  
  3132.  
  3133.                    Details:  The MakeWindow routine can display a wide
  3134.                    variety of windows in several interesting ways. You
  3135.                    may specify any  one  of  ten  different  types  of
  3136.                    windows  made  from any of 6 different frame types,
  3137.                    with any color window  shadow  (or  none  at  all).
  3138.                    Your windows can be drawn normally onto the screen,
  3139.                    or exploded onto the screen for visual impact.
  3140.  
  3141.                    Creating a window involves a little planning.   You
  3142.                    must  know  how big you want your window to be, and
  3143.                    where you want it on the screen.  You  must  decide
  3144.                    the   colors   for   the  window,  and  any  visual
  3145.                    embellishments  you  want,  such  as   shadows   or
  3146.                    exploding  windows.   Let's  go through the step by
  3147.                    step process of defining a window.
  3148.  
  3149.  
  3150.                                                                page 48
  3151.  
  3152.  
  3153.  
  3154.                    We shall assume that we are designing a window that
  3155.                    will hold an error message.  The message will never
  3156.                    be more than three lines long.  To  make  it  stand
  3157.                    out,  we will place the window in the middle of the
  3158.                    screen,  with  bright  yellow   text   on   a   red
  3159.                    background.   The  window will be exploded onto the
  3160.                    screen, and will have a black shadow.  We will  add
  3161.                    a  label  to  the  window  indicating that it is an
  3162.                    error message.
  3163.  
  3164.                    To create a window with space for three  lines,  we
  3165.                    must  allow  5  lines of window (3 for the text and
  3166.                    one each for  the  top  and  bottom  lines  of  the
  3167.                    frame).   Therefore  our top row will be 11 and our
  3168.                    bottom row will be 15.  This makes 5 lines,  so  we
  3169.                    set our parameters like this:
  3170.  
  3171.                                        topRow = 11
  3172.                                        botRow = 15
  3173.  
  3174.                    Our  lines  will always be less than 65 characters,
  3175.                    so let's allow 70 characters of width.  This  would
  3176.                    make  our  left  column  6 and our right column 75,
  3177.                    like this:
  3178.  
  3179.                                       leftCol = 6
  3180.                                       rightCol = 75
  3181.  
  3182.                    To set our foreground  and  background  colors,  we
  3183.                    simply make the proper assignments:
  3184.  
  3185.                             foreColor% = 14   ' Bright Yellow
  3186.                             backColor% = 4    ' Red
  3187.  
  3188.                    Now  comes  the  interesting  part.  We must decide
  3189.                    what type of window we want to  use.   Below  is  a
  3190.                    table   that   illustrates  the  ten  window  types
  3191.                    available with the MakeWindow routine:
  3192.  
  3193.  
  3194.  
  3195.  
  3196.  
  3197.  
  3198.  
  3199.  
  3200.  
  3201.  
  3202.  
  3203.  
  3204.  
  3205.  
  3206.  
  3207.  
  3208.  
  3209.  
  3210.  
  3211.  
  3212.                                                                page 49
  3213.  
  3214.  
  3215.  
  3216.                                       WINDOW  TYPES
  3217.                      ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
  3218.                      │   Type  0   │ │   Type  1   │ │   Type  2   │
  3219.                      │             │ ├─────────────┤ ├─────────────┤
  3220.                      │             │ │             │ │             │
  3221.                      │             │ │             │ │             │
  3222.                      │             │ │             │ │             │
  3223.                      │             │ ├─────────────┤ │             │
  3224.                      │             │ │             │ │             │
  3225.                      └─────────────┘ └─────────────┘ └─────────────┘
  3226.                      ┌─────────────┐ ┌──────┬──────┐ ┌─────────────┐
  3227.                      │   Type  3   │ │ Type │      │ │   Type  5   │
  3228.                      │             │ │   4  │      │ │             │
  3229.                      │             │ │      │      │ │             │
  3230.                      │             │ │      │      │ ├─────────────┤
  3231.                      │             │ │      │      │ │             │
  3232.                      ├─────────────┤ │      │      │ │             │
  3233.                      │             │ │      │      │ │             │
  3234.                      └─────────────┘ └──────┴──────┘ └─────────────┘
  3235.                      ┌──────┬──────┐ ┌─────────────┐ ┌──────┬──────┐
  3236.                      │ Type │      │ │   Type  7   │ │      │      │
  3237.                      │   6  │      │ ├──────┬──────┤ │      │      │
  3238.                      │      │      │ │      │      │ │      │      │
  3239.                      ├──────┼──────┤ │      │      │ │      │      │
  3240.                      │      │      │ │      │      │ │      │      │
  3241.                      │      │      │ │      │      │ ├──────┴──────┤
  3242.                      │      │      │ │      │      │ │   Type  8   │
  3243.                      └──────┴──────┘ └──────┴──────┘ └─────────────┘
  3244.                                      ┌─────────────┐
  3245.                                      │   Type  9   │
  3246.                                      ├──────┬──────┤
  3247.                                      │      │      │
  3248.                                      │      │      │
  3249.                                      │      │      │
  3250.                                      ├──────┴──────┤
  3251.                                      │             │
  3252.                                      └─────────────┘
  3253.  
  3254.                    We will be using window type 0, since we don't need
  3255.                    any   internal  lines.   We  set  our  window  type
  3256.                    parameter to 0:
  3257.  
  3258.                                      windowType% = 0
  3259.  
  3260.                    The second parameter integral to the appearance  of
  3261.                    the  window  is the frame type.  This indicates the
  3262.                    types of lines to use  when  drawing  the  windows.
  3263.                    Below is a table illustrating the 6 different frame
  3264.                    types available in the MakeWindow routine:
  3265.  
  3266.  
  3267.  
  3268.  
  3269.  
  3270.  
  3271.  
  3272.  
  3273.  
  3274.                                                                page 50
  3275.  
  3276.  
  3277.  
  3278.                                        FRAME TYPES
  3279.                      ┌─────────────┐ ╔═════════════╗ ╓─────────────╖
  3280.                      │             │ ║             ║ ║             ║
  3281.                      ├─────────────┤ ╠═════════════╣ ╟─────────────╢
  3282.                      │             │ ║             ║ ║             ║
  3283.                      │   Type  0   │ ║   Type  1   ║ ║   Type  2   ║
  3284.                      │             │ ║             ║ ║             ║
  3285.                      ├─────────────┤ ╠═════════════╣ ╟─────────────╢
  3286.                      │             │ ║             ║ ║             ║
  3287.                      └─────────────┘ ╚═════════════╝ ╙─────────────╜
  3288.                      ╒═════════════╕ ╔═════════════╗ ┌─────────────┐
  3289.                      │             │ ║             ║ │             │
  3290.                      ╞═════════════╡ ╟─────────────╢ ╞═════════════╡
  3291.                      │             │ ║             ║ │             │
  3292.                      │   Type  3   │ ║   Type  4   ║ │   Type  5   │
  3293.                      │             │ ║             ║ │             │
  3294.                      ╞═════════════╡ ╟─────────────╢ ╞═════════════╡
  3295.                      │             │ ║             ║ │             │
  3296.                      ╘═════════════╛ ╚═════════════╝ └─────────────┘
  3297.  
  3298.                    We will be using frame type 1, a double line frame.
  3299.                    All  we have to do is set the parameter variable to
  3300.                    the appropriate value:
  3301.  
  3302.                                      frameType% = 1
  3303.  
  3304.                    The  next parameter to set is the shadow color.  We
  3305.                    will be using a shadow to give  our  window  a  3-D
  3306.                    effect.  You can make the shadow any color you like
  3307.                    (0  -  16),  but  0 (black) or 16 provides the best
  3308.                    effect. If you do not want a shadow on your window,
  3309.                    send a value of -1 for the shadow color.  We want a
  3310.                    black shadow:
  3311.  
  3312.                                     shadowColor% = 0
  3313.  
  3314.                    Shadow type 16 is a special type of shadow, and  is
  3315.                    a  new  feature  in  version  1.5.  What it does is
  3316.                    place  a window shadow in the normal  location, but
  3317.                    the  type  of  shadow  is different.  It leaves the
  3318.                    characters in the shadow visible, but changes their
  3319.                    colors to plain white.  For most application,  this
  3320.                    provides  a  MUCH  more  realistic  shadowing,  3-D
  3321.                    effect.  I have adopted it almost universally in my
  3322.                    programs.
  3323.  
  3324.                    To grab the user's attention, and to add a touch of
  3325.                    professionalism, we will explode  the  window  onto
  3326.                    the  screen.   Exploding  the  window means make it
  3327.                    appear to grow or expand onto the screen from  it's
  3328.                    center  point out to its full size.  There are four
  3329.                    possible values for the explode type parameter:
  3330.  
  3331.  
  3332.  
  3333.  
  3334.  
  3335.  
  3336.                                                                page 51
  3337.  
  3338.  
  3339.  
  3340.                    To do this...        ...use this Explode Type Value
  3341.                    ---------------------------------------------------
  3342.                    ■ Place the window on
  3343.                      the screen normally  . . . . . . . . . . . . . 0
  3344.                    ■ Explode the window
  3345.                      using "Auto" mode  . . . . . . . . . . . . . . 1
  3346.                    ■ Explode the window
  3347.                      with a horizontal bias . . . . . . . . . . . . 2
  3348.                    ■ Explode the window
  3349.                      with a vertical bias . . . . . . . . . . . . . 3
  3350.  
  3351.                    Placing  the  window  on  the screen normally means
  3352.                    display it in the ordinary top-to-bottom fashion as
  3353.                    quickly as possible.  "Auto" mode  means  that  the
  3354.                    window  explosion is automatically adjusted so that
  3355.                    the corners of the window reach the maximum size at
  3356.                    the same time.  The horizontal bias  mode  is  used
  3357.                    for  very  wide  and  short windows (like our error
  3358.                    message example).  Vertical bias mode is  used  for
  3359.                    tall,  narrow windows.  You can experiment with the
  3360.                    modes for any particular window and see which  mode
  3361.                    suits  your  needs.   If  you  want to explode your
  3362.                    windows, "Auto" mode is a good place to start.
  3363.  
  3364.                    For our explode type, since our window is wide  and
  3365.                    short,  we  will  use  mode  2, the Horizontal Bias
  3366.                    mode:
  3367.                                     explodeType% = 2
  3368.  
  3369.                    Our  last  item  of  interest for our window is the
  3370.                    label.  The label is a text header that goes on the
  3371.                    upper-left border of the window, like this:
  3372.  
  3373.                               ╔═╡ The LABEL ╞═════════════╗
  3374.                               ║                           ║
  3375.                               ║                           ║
  3376.                               ║                           ║
  3377.                               ╚═══════════════════════════╝
  3378.  
  3379.                    Since our example window will be used to display an
  3380.                    error message, our label will say this:
  3381.  
  3382.                                    label$ = " Error! "
  3383.  
  3384.                    The  final  step  is  to  make  the  call  to   the
  3385.                    MakeWindow  subprogram.   The  call  will look like
  3386.                    this:
  3387.  
  3388.                          MakeWindow topRow, leftCol, botRow,
  3389.                                      rightCol, foreColor%, backColor%,
  3390.                                      windowType%, frameType%,
  3391.                                      shadowColor%, explodeType%,
  3392.                                      label$
  3393.  
  3394.                    In your program, this would  all  be  on  a  single
  3395.                    line.   It's  broken up here onto several lines for
  3396.                    readability.
  3397.  
  3398.                                                                page 52
  3399.  
  3400.  
  3401.  
  3402.                    Once your window has been displayed by  MakeWindow,
  3403.                    you  can do whatever you want with it: fill it with
  3404.                    an error message, for example.  MakeWindow can give
  3405.                    your programs a very professional polish.
  3406.  
  3407.  
  3408.                    Example:  Two examples will be presented here.  The
  3409.                    first  will  be  a  reiteration  of   the   example
  3410.                    described  in  the  Details  above  -  a  window to
  3411.                    display an error message.  It will be in  the  long
  3412.                    form, with each parameter of the MakeWindow routine
  3413.                    represented by a variable.  The second example will
  3414.                    be  a  shorthand version of the same example, using
  3415.                    actual values (literals) instead of variables.
  3416.  
  3417.                    ' MakeWindow example 1 begins
  3418.                    ' Assign screen coordinates for window
  3419.                    topRow = 11: botRow = 15
  3420.                    leftCol = 6: rightCol = 75
  3421.  
  3422.                    ' Assign colors for the window
  3423.                    foreColor% = 14    ' Bright Yellow
  3424.                    backColor% = 4     ' Red
  3425.  
  3426.                    'Assign window and frame type parameters
  3427.                    windowType% = 0
  3428.                    frameType% = 1
  3429.  
  3430.                    ' Assign shadow color and explode type
  3431.                    shadowColor% = 0   ' Black shadow
  3432.                    explodeType% = 2   ' Horizontal bias mode
  3433.  
  3434.                    ' Assign our window label
  3435.                    label$ = " Error! "
  3436.  
  3437.                    ' Perform the call to MakeWindow
  3438.                    MakeWindow topRow, leftCol, botRow,
  3439.                               rightCol, foreColor%, backColor%,
  3440.                               windowType%, frameType%,
  3441.                               shadowColor%, explodeType%,
  3442.                               label$
  3443.                    ' MakeWindow example 1 ends
  3444.  
  3445.                    The second example will be shorter  and  easier  to
  3446.                    code  initially, but may be harder to understand if
  3447.                    you come back to your program a month later.
  3448.  
  3449.                    ' MakeWindow example 2 begins
  3450.                    MakeWindow 11, 6, 15, 75, 14, 4, 0, 1, 0, 2,
  3451.                               " Error! "
  3452.                    ' MakeWindow example 2 ends
  3453.  
  3454.                    This second example is  functionally  identical  to
  3455.                    example 1.
  3456.  
  3457.  
  3458.  
  3459.  
  3460.                                                                page 53
  3461.  
  3462.  
  3463.  
  3464.                    If  you  need  more examples of MakeWindow, you can
  3465.                    peruse  the  source  code  for  the  DEMO  and  REF
  3466.                    programs.
  3467.  
  3468.  
  3469.                    Known Limitations: None.
  3470.  
  3471.  
  3472.  
  3473.  
  3474.  
  3475.  
  3476.  
  3477.  
  3478.  
  3479.  
  3480.  
  3481.  
  3482.  
  3483.  
  3484.  
  3485.  
  3486.  
  3487.  
  3488.  
  3489.  
  3490.  
  3491.  
  3492.  
  3493.  
  3494.  
  3495.  
  3496.  
  3497.  
  3498.  
  3499.  
  3500.  
  3501.  
  3502.  
  3503.  
  3504.  
  3505.  
  3506.  
  3507.  
  3508.  
  3509.  
  3510.  
  3511.  
  3512.  
  3513.  
  3514.  
  3515.  
  3516.  
  3517.  
  3518.  
  3519.  
  3520.  
  3521.  
  3522.                                                                page 54
  3523.  
  3524.  
  3525.  
  3526.  
  3527.          Subprogram MULTIMENU
  3528.          -------------------------------------------------------------
  3529.  
  3530.  
  3531.                    Purpose:  To create a pull-down menu system for any
  3532.                    application program.  Number of  menus  is  limited
  3533.                    only by amount of room on one line.
  3534.  
  3535.  
  3536.                    Usage: MuiltMenu menusArray$(), numEntries%(),
  3537.                                     menuTitles%(), justify$, marker$,
  3538.                                     shadowCode%, fg%, bg%, hfg%, hbg%,
  3539.                                     qfg%, qbg%, menuSelected%,
  3540.                                     menuEntrySelected%
  3541.  
  3542.                              menusArray$() - a  two-dimensional  array
  3543.                                     of strings that holds all the menu
  3544.                                     choices
  3545.                              numEntries%() - an array of integers that
  3546.                                     holds the actual number of choices
  3547.                                     for each menu
  3548.                              menuTitles$()  - an array of strings that
  3549.                                     holds the menu names,  or  titles,
  3550.                                     that are displayed on the top line
  3551.                              justify$ - A single character that  tells
  3552.                                     the  routine  how  to  align   the
  3553.                                     choices within the menu window
  3554.                              marker$ - A single character  that  tells
  3555.                                     the  routine  which  character  to
  3556.                                     look for that indicates the "Quick
  3557.                                     Access" key for each menu choice.
  3558.                              shadowCode% - a number from -1 to 16 that
  3559.                                     tells the  routine  what  kind  of
  3560.                                     shadow to use for the menu windows
  3561.                              fg%,  bg% - the foreground and background
  3562.                                     colors of the normal menu entries,
  3563.                                     as well as the unhighlighted  menu
  3564.                                     titles on the top line
  3565.                              hfg%,hbg% - the foreground and background
  3566.                                     colors  of  the  highlighted  menu
  3567.                                     choices,   as    well    as    the
  3568.                                     highlighted menu titles on the top
  3569.                                     line
  3570.                              qfg%,qbg% - the foreground and background
  3571.                                     colors of the "Quick Access"  keys
  3572.                                     for  the  menu choices, as well as
  3573.                                     for the menu  titles  on  the  top
  3574.                                     line
  3575.                              menuSelected% - this is an OUT parameter,
  3576.                                     meaning that when  it  comes  into
  3577.                                     the routine, it has no value. When
  3578.                                     the routine returns, this variable
  3579.                                     contains  the  number  of the menu
  3580.                                     the user selected
  3581.  
  3582.  
  3583.  
  3584.                                                                page 55
  3585.  
  3586.  
  3587.                              menuEntrySelected%  -  this  is  an   OUT
  3588.                                     parameter,  meaning  that  when it
  3589.                                     comes into the routine, it has  no
  3590.                                     value.  When  the routine returns,
  3591.                                     this variable contains the  number
  3592.                                     of  the entry the user selected on
  3593.                                     the particular menu they selected
  3594.  
  3595.  
  3596.                    Details: MultiMenu is a very capable pull-down menu
  3597.                    system you can use for any of  your  programs.   It
  3598.                    will  do  most  everything automatically, including
  3599.                    making a window for each menu to the  proper  size,
  3600.                    placing the menus on the screen in the right place,
  3601.                    and   provides  a  wide  variety  of  movement  and
  3602.                    selection keys.
  3603.  
  3604.                    Granted,  this  routine  looks  a  bit daunting and
  3605.                    complicated.  It's not, really.  All it requires is
  3606.                    a  little  planning,  and  you  can  have  a  great
  3607.                    interface  for  your program.  What it creates is a
  3608.                    pull-down menu system very much like the  menus  in
  3609.                    QuickBASIC.   Let's take this one step at a time as
  3610.                    we discuss how to create a menu.
  3611.  
  3612.                    The first step is to plan carefully ahead  of  time
  3613.                    all   the   information  your  menu  will  require,
  3614.                    including:
  3615.  
  3616.                              - What are the all the functions  I  want
  3617.                                on my menu system?  Write them down.
  3618.  
  3619.                              - How   do  I  want  to  divide  all  the
  3620.                                functions in  my  program  into  menus,
  3621.                                i.e.,   categories?   Write  this  down
  3622.                                also.
  3623.  
  3624.                    You should now have a good idea of  how  your  menu
  3625.                    system  will be organized.  Your categories are the
  3626.                    individual  menus,  and  the  functions  in   those
  3627.                    categories are the individual menu choices.  If you
  3628.                    would  like an example of this, you can look at the
  3629.                    QuickBASIC menus and how they're organized, or  the
  3630.                    menu  system on the Screen Builder program.  Screen
  3631.                    Builder used MultiMenu for its menus.
  3632.  
  3633.                    The only other planning you'll need to do is decide
  3634.                    what colors you want your menus to use.   From  now
  3635.                    on,  it gets easier.  The first step in writing the
  3636.                    code is to set up the three arrays  that  MultiMenu
  3637.                    needs.   The  first  is  the worst, so  let's  take
  3638.                    some care with it.
  3639.  
  3640.                    The first array is a two-dimensional array, meaning
  3641.                    it has two index values.  The first value indicates
  3642.                    the  MENU  we're  talking  about,  and  the  second
  3643.                    indicates the CHOICE on the menu referred to by the
  3644.                    first index.  Assume we are creating a menu  system
  3645.  
  3646.                                                                page 56
  3647.  
  3648.  
  3649.  
  3650.                    that  will  have 3 menus in it, with a MAXIMUM of 5
  3651.                    choices per menu.  We don't have to use all 5,  but
  3652.                    we  must  allow  for  the  largest case.  Our array
  3653.                    dimension would look like this:
  3654.  
  3655.                              DIM menusArray$(1 TO 3, 1 TO 5)
  3656.  
  3657.                    Pretty easy.  The first value, 3, is the number  of
  3658.                    menus  in  our  system, and the second value, 5, is
  3659.                    the maximum possible number of  choices  per  menu.
  3660.                    The  next step is to assign the actual menu choices
  3661.                    to the array.  In our example, we will be  creating
  3662.                    a   menu  system  for  a  fictitious  Typing  Tutor
  3663.                    program. Our 3 menu categories are:
  3664.  
  3665.                              1.  File
  3666.  
  3667.                              2.  Lessons
  3668.  
  3669.                              3.  Practice
  3670.  
  3671.                    Adding our individual functions to the menus  would
  3672.                    make our outline look like this:
  3673.  
  3674.                              1.  File
  3675.                                  1. Start as New Student
  3676.                                  2. Load an Old Student
  3677.                                  3. Save a Student
  3678.                                  4. Quit
  3679.  
  3680.                              2.  Lessons
  3681.                                  1. Beginner Lesson
  3682.                                  2. Intermediate Lesson 1
  3683.                                  3. Intermediate Lesson 2
  3684.                                  4. Intermediate Lesson 3
  3685.                                  5. Advanced Lesson
  3686.  
  3687.                              3.  Practice
  3688.                                  1. Beginner Practice
  3689.                                  2. Intermediate Practice 1
  3690.                                  3. Intermediate Practice 2
  3691.                                  4. Intermediate Practice 3
  3692.                                  5. Advanced Practice
  3693.  
  3694.                    The number on our main outline headings  (the  menu
  3695.                    titles,  1-3), correspond to the first index of our
  3696.                    array, while the numbers on  the  subheadings  (the
  3697.                    individual  menu  choices) correspond to the second
  3698.                    array index.  We can now assign these values to our
  3699.                    array as follows:
  3700.  
  3701.                         ' The first menu's choices
  3702.                         menusArray$(1, 1) = "Start as New Student"
  3703.                         menusArray$(1, 2) = "Load an Old Student"
  3704.                         menusArray$(1, 3) = "Save a Student"
  3705.                         menusArray$(1, 4) = "Quit Typing Tutor"
  3706.  
  3707.  
  3708.                                                                page 57
  3709.  
  3710.  
  3711.  
  3712.                         ' The second menu's choices
  3713.                         menusArray$(2, 1) = "Beginner Lesson"
  3714.                         menusArray$(2, 2) = "Intermediate Lesson 1"
  3715.                         menusArray$(2, 3) = "Intermediate Lesson 2"
  3716.                         menusArray$(2, 4) = "Intermediate Lesson 3"
  3717.                         menusArray$(2, 5) = "Advanced Lesson"
  3718.  
  3719.                         ' The third menu's choices
  3720.                         menusArray$(3, 1) = "Beginner Practice"
  3721.                         menusArray$(3, 2) = "Intermediate Practice 1"
  3722.                         menusArray$(3, 3) = "Intermediate Practice 2"
  3723.                         menusArray$(3, 4) = "Intermediate Practice 3"
  3724.                         menusArray$(3, 5) = "Advanced Practice"
  3725.  
  3726.                    The  next thing to do is deal with the second array
  3727.                    for this routine.  This array tells  MultiMenu  the
  3728.                    actual  number of choices for each menu.  This is a
  3729.                    normal one-dimensional array, and the  array  index
  3730.                    corresponds  to  the menus.  Here we will dimension
  3731.                    the array, and then fill it with values:
  3732.  
  3733.                         ' Dimension our array first
  3734.                         DIM numEntries%(1 TO 3)
  3735.  
  3736.                         ' Now enter values.
  3737.                         numEntries%(1) = 4  '4 entries in first menu
  3738.                         numEntries%(2) = 5  '5 entries in second menu
  3739.                         numEntries%(3) = 5  '5 entries in third menu
  3740.  
  3741.                    And  now  our  last  array,  which  is  an array of
  3742.                    strings that tells  MultiMenu  the  titles  of  our
  3743.                    menus.   It's  a  normal,  one-dimensional array of
  3744.                    strings, and the index refers to the  menus.   Note
  3745.                    that the values we place in are the headings in our
  3746.                    outline above.
  3747.  
  3748.                         ' Dimension an array first
  3749.                         DIM menuTitles$(1 TO 3)
  3750.  
  3751.                         ' Now add the menu titles
  3752.                         menuTitles$(1) = "File"
  3753.                         menuTitles$(2) = "Lessons"
  3754.                         menuTitles$(3) = "Practice"
  3755.  
  3756.                    That's  the  second  hardest  part.   The  rest  is
  3757.                    simple. First, you must decide  how  you  want  the
  3758.                    entries  aligned  within  the  window  that will be
  3759.                    created for them.  You can have the left-justified,
  3760.                    centered, or right-justified.  You  tell  MultiMenu
  3761.                    how  to  do  this by sending it a single character.
  3762.                    Send an "L" for left-justified, a "C" for centered,
  3763.                    or an "R" for right-justified.  Let's say  we  want
  3764.                    our  menu choices to be left justified, so we would
  3765.                    use an L, like this:
  3766.  
  3767.                         ' Set the justification type
  3768.                         justify$ = "L"
  3769.  
  3770.                                                                page 58
  3771.  
  3772.  
  3773.  
  3774.                    Now  you  must decide on a marker character to use.
  3775.                    The marker character is imbedded in the menu titles
  3776.                    and the menu  choices  and  tells  MultiMenu  which
  3777.                    characters  to  use as "Quick Access" keys.  Simply
  3778.                    place the marker  character  in  the  string  right
  3779.                    before  the character you want MultiMenu to use for
  3780.                    each choice.  We now have to modify our menu titles
  3781.                    and  menu  choices  to   incorporate   the   marker
  3782.                    character.  We will use the "^" for our marker.
  3783.  
  3784.                         ' The first menu's choices
  3785.                         menusArray$(1, 1) = "Start as ^New Student"
  3786.                         menusArray$(1, 2) = "Load an ^Old Student"
  3787.                         menusArray$(1, 3) = "^Save a Student"
  3788.                         menusArray$(1, 4) = "^Quit Typing Tutor"
  3789.  
  3790.                         ' The second menu's choices
  3791.                         menusArray$(2, 1) = "^Beginner Lesson"
  3792.                         menusArray$(2, 2) = "Intermediate Lesson ^1"
  3793.                         menusArray$(2, 3) = "Intermediate Lesson ^2"
  3794.                         menusArray$(2, 4) = "Intermediate Lesson ^3"
  3795.                         menusArray$(2, 5) = "^Advanced Lesson"
  3796.  
  3797.                         ' The third menu's choices
  3798.                         menusArray$(3, 1) = "^Beginner Practice"
  3799.                         menusArray$(3, 2) = "Intermediate Practice ^1"
  3800.                         menusArray$(3, 3) = "Intermediate Practice ^2"
  3801.                         menusArray$(3, 4) = "Intermediate Practice ^3"
  3802.                         menusArray$(3, 5) = "^Advanced Practice"
  3803.  
  3804.                         ' The menu titles
  3805.                         menuTitles$(1) = "^File"
  3806.                         menuTitles$(2) = "^Lessons"
  3807.                         menuTitles$(3) = "^Practice"
  3808.  
  3809.                    Note that when assigning "Quick Access" keys WITHIN
  3810.                    a menu, you must use a unique  character  for  each
  3811.                    menu choice.  Also, if you do not wish to implement
  3812.                    the "Quick Access" keys, then simply do  not  imbed
  3813.                    any marker characters in the choice/title strings.
  3814.  
  3815.                    Now decide on a type of shadow for the menu window.
  3816.                    You have the same shadow types available  as  those
  3817.                    in the MakeWindow routine, summarized below:
  3818.  
  3819.                             Shadow Value...         ...Result
  3820.                             ---------------------------------
  3821.                             -1 . . . . . . . . . .  No shadow
  3822.                             0-15 . . . . Shadow of this color
  3823.                             16 . . . Special character shadow
  3824.  
  3825.                    Lastly,  you  must decide on colors to use.  Assign
  3826.                    colors to your menu using the following parameters:
  3827.  
  3828.                         fg%, bg% - normal menu choices and titles
  3829.                     hfg%, hbg% - highlighted menu choices and titles
  3830.                             qfg%, qbg% - "Quick Access" keys
  3831.  
  3832.                                                                page 59
  3833.  
  3834.  
  3835.  
  3836.                    The  last   two   parameters,   menuSelected%   and
  3837.                    MenuEntrySelected%,  do  not  need  values when you
  3838.                    call MultiMenu.  MultiMenu will FILL IN values  for
  3839.                    these variables when it returns, indicating
  3840.  
  3841.                         The menu the user selected (menuSelected)
  3842.                         The choice on that menu the user selected
  3843.                                    (menuEntrySelected)
  3844.  
  3845.                    When  MultiMenu  returns, you can use the values in
  3846.                    these variables to decide what to do  based on  the
  3847.                    user's  choice.  Let's move on to an example now to
  3848.                    see how this all fits together.
  3849.  
  3850.  
  3851.                    Example: We'll use the same example we used  above,
  3852.                    except  now  we'll  piece  it  all together.  We're
  3853.                    creating a fictitious Typing Tutor.
  3854.  
  3855.                    ' Define a couple quick constants
  3856.                    CONST FALSE = 0, TRUE = NOT FALSE
  3857.  
  3858.                    ' MultiMenu example begins
  3859.                    ' Dimension arrays for MultiMenu call
  3860.                    DIM menusArray$(1 TO 3, 1 TO 5)
  3861.                    DIM numEntries%(1 TO 3)
  3862.                    DIM menuTitles$(1 TO 3)
  3863.  
  3864.                    ' Assign values to our menu choices array
  3865.                    ' First menu
  3866.                    menusArray$(1, 1) = "Start as ^New Student"
  3867.                    menusArray$(1, 2) = "Load an ^Old Student"
  3868.                    menusArray$(1, 3) = "^Save a Student"
  3869.                    menusArray$(1, 4) = "^Quit Typing Tutor"
  3870.  
  3871.                    ' Second menu
  3872.                    menusArray$(2, 1) = "^Beginner Lesson"
  3873.                    menusArray$(2, 2) = "Intermediate Lesson ^1"
  3874.                    menusArray$(2, 3) = "Intermediate Lesson ^2"
  3875.                    menusArray$(2, 4) = "Intermediate Lesson ^3"
  3876.                    menusArray$(2, 5) = "^Advanced Lesson"
  3877.  
  3878.                    ' Third menu
  3879.                    menusArray$(3, 1) = "^Beginner Practice"
  3880.                    menusArray$(3, 2) = "Intermediate Practice ^1"
  3881.                    menusArray$(3, 3) = "Intermediate Practice ^2"
  3882.                    menusArray$(3, 4) = "Intermediate Practice ^3"
  3883.                    menusArray$(3, 5) = "^Advanced Practice"
  3884.  
  3885.                    ' Assign the number of entries per menu to
  3886.                    ' their array
  3887.                    numEntries%(1) = 4
  3888.                    numEntries%(2) = 5
  3889.                    numEntries%(3) = 5
  3890.  
  3891.  
  3892.  
  3893.  
  3894.                                                                page 60
  3895.  
  3896.  
  3897.  
  3898.                    ' Assign the menu titles to their array
  3899.                    menuTitles$(1) = "^File"
  3900.                    menuTitles$(2) = "^Lessons"
  3901.                    menuTitles$(3) = "^Practice
  3902.  
  3903.                    ' Assign a justification type
  3904.                    justify$ = "L"
  3905.  
  3906.                    ' Assign a marker character
  3907.                    marker$ = "^"
  3908.  
  3909.                    ' Set a shadow type
  3910.                    shadowCode% = 16
  3911.  
  3912.                    ' Assign colors.  If machine is running color,
  3913.                    ' use colors.  If mono, use only white, black,
  3914.                    ' and bright white.  Determine if color using
  3915.                    ' QBSCR ColorChk routine.
  3916.                    if ColorChk then   ' Machine is color
  3917.                        fg% = 7    ' White
  3918.                        bg% = 1    ' Blue
  3919.                        hfg% = 14  ' Yellow
  3920.                        hbg% = 0   ' Black
  3921.                        qfg% = 15  ' Bright White
  3922.                        qbg% = 1   ' Blue
  3923.                    else  ' Machine is monochrome
  3924.                        fg% = 0    ' Black
  3925.                        bg% = 7    ' White
  3926.                        hfg% = 15  ' Bright White
  3927.                        hbg% = 0   ' Black
  3928.                        qfg% = 15  ' Bright White
  3929.                        qbg% = 0   ' Black
  3930.                    end if
  3931.  
  3932.                    ' Now make the call to MultiMenu.  Do this inside a
  3933.                    ' loop, and loop until the user selects quit.  Some
  3934.                    ' lines may be broken onto two rows, since this is
  3935.                    ' only a text file in my word processor.  Note that
  3936.                    ' the last two parameters have no values going into
  3937.                    ' MultiMenu.  They will be filled with values
  3938.                    ' INSIDE MultiMenu for our use afterwards.
  3939.                    userDone% = FALSE
  3940.                    DO
  3941.                        MultiMenu menusArray$(), numEntries%(),
  3942.                                  menuTitles$(), justify$, marker$,
  3943.                                  shadowCode%, fg%, bg%, hfg%, hbg%,
  3944.                                  qfg%, qbg%, menuSelected%,
  3945.                                  menuEntrySelected%
  3946.  
  3947.  
  3948.  
  3949.  
  3950.  
  3951.  
  3952.  
  3953.  
  3954.  
  3955.  
  3956.                                                                page 61
  3957.  
  3958.  
  3959.  
  3960.                        ' At this point, we have returned from
  3961.                        ' MultiMenu, and must decide what to do
  3962.                        ' based on the user's choice, stored now in
  3963.                        ' the variables menuSelected% and
  3964.                        ' menuEntrySelected%.  For this, we use
  3965.                        ' the BASIC CASE statement.
  3966.                        SELECT CASE menuSelected%
  3967.                        CASE 1   ' File Menu
  3968.                            SELECT CASE menuEntrySelected%
  3969.                            CASE 1   ' Start as New Student
  3970.                                ' Run routine to start as new student
  3971.                            CASE 2   ' Load an Old Student
  3972.                                ' Run routine to load old student
  3973.                            CASE 3   ' Save a Student
  3974.                                ' Run routine to save student
  3975.                            CASE 4   ' Quit Typing Tutor
  3976.                                ' Run routine to quit.  In this case,
  3977.                                ' we set our loop flag to TRUE
  3978.                                userDone% = TRUE
  3979.                        CASE 2   ' Lessons Menu
  3980.                            SELECT CASE menuEntrySelected%
  3981.                            CASE 1   ' Beginner Lesson
  3982.                                ' Run routine for Beginner Lesson
  3983.                            CASE 2   ' Intermediate Lesson 1
  3984.                                ' Run code for Intermediate Lesson 1
  3985.                            CASE 3   ' Intermediate Lesson 2
  3986.                                ' Run code for Intermediate Lesson 2
  3987.                            CASE 4   ' Intermediate Lesson 3
  3988.                                ' Run code for Intermediate Lesson 3
  3989.                            CASE 5   ' Advanced Lesson
  3990.                                ' Run code for Advanced Lesson
  3991.                        CASE 3   ' Practice Menu
  3992.                            SELECT CASE menuEntrySelected%
  3993.                            CASE 1   ' Beginner Practice
  3994.                                ' Run code for Beginner Practice
  3995.                            CASE 2   ' Intermediate Practice 1
  3996.                                ' Run Intermediate Practice 1
  3997.                            CASE 3   ' Intermediate Practice 2
  3998.                                ' Run Intermediate Practice 2
  3999.                            CASE 4   ' Intermediate Practice 3
  4000.                                ' Run Intermediate Practice 3
  4001.                            CASE 5   ' Advanced Practice
  4002.                                ' Run Advanced Practice code
  4003.                        CASE 0   ' User hit ESC - aborted menu
  4004.                            ' Here you could do whatever necessary to
  4005.                            ' handle the ESC key.  If your menu is up
  4006.                            ' all the time, simply ignore it.  If your
  4007.                            ' menu is supposed to go away when the ESC
  4008.                            ' key is hit, then make it go away.  In
  4009.                            ' this example, the menu goes away, so we
  4010.                            ' will exit our loop by setting the loop
  4011.                            ' flag to TRUE.
  4012.                            userDone% = TRUE
  4013.                        END SELECT
  4014.                    LOOP UNTIL userDone%
  4015.  
  4016.                    ' MultiMenu example ends...finally
  4017.  
  4018.                                                                page 62
  4019.  
  4020.  
  4021.  
  4022.                    Known  Limitations:  The number of menus allowed is
  4023.                    limited by the size  of  a  screen  row.   It  will
  4024.                    handle  as  many as you can fit on one row.  Number
  4025.                    of menu entries per menu is limited by  the  number
  4026.                    of  rows  on  a  screen.   If  you are using a menu
  4027.                    shadow, the number of entries per menu  is  limited
  4028.                    to 21.  Without a shadow, it's 22.
  4029.  
  4030.  
  4031.  
  4032.  
  4033.  
  4034.  
  4035.  
  4036.  
  4037.  
  4038.  
  4039.  
  4040.  
  4041.  
  4042.  
  4043.  
  4044.  
  4045.  
  4046.  
  4047.  
  4048.  
  4049.  
  4050.  
  4051.  
  4052.  
  4053.  
  4054.  
  4055.  
  4056.  
  4057.  
  4058.  
  4059.  
  4060.  
  4061.  
  4062.  
  4063.  
  4064.  
  4065.  
  4066.  
  4067.  
  4068.  
  4069.  
  4070.  
  4071.  
  4072.  
  4073.  
  4074.  
  4075.  
  4076.  
  4077.  
  4078.  
  4079.  
  4080.                                                                page 63
  4081.  
  4082.  
  4083.  
  4084.  
  4085.          Subprogram OFFCENTER
  4086.          -------------------------------------------------------------
  4087.  
  4088.  
  4089.                    Purpose: To center a text string between two points
  4090.                    on the screen that are not themselves centered.
  4091.  
  4092.  
  4093.                    Usage: OffCenter st$, row%, leftCol, rightCol
  4094.  
  4095.                             st$ - The string to center
  4096.                             row%  -  The  row of the screen  on  which
  4097.                                  to center the specified string.
  4098.                             leftCol - The left-most column  to  center
  4099.                                  the text between.
  4100.                             rightCol - The right-most column to center
  4101.                                  the text between.
  4102.  
  4103.  
  4104.                    Details:  This  routine  is useful when you want to
  4105.                    center text between two points on the  screen  that
  4106.                    are  themselves  not  centered  on the screen.  For
  4107.                    example, you  may  have  a  window  on  the  screen
  4108.                    between  columns  5 and 30, but want to center some
  4109.                    text inside the window,  relative  to  the  window.
  4110.                    This is where OffCenter is useful.
  4111.  
  4112.                    To  Center  a  text string between two points, call
  4113.                    OffCenter and  tell  it  the  string  you  want  to
  4114.                    center,  the  row you want the text on, and the two
  4115.                    points to center the text between.
  4116.  
  4117.  
  4118.                    Example: Let's say we have a window on  the  screen
  4119.                    that  begins on column 5 and ends on column 30.  We
  4120.                    then need to center the text "ERROR WARNING" on the
  4121.                    first row of the window, which happens to be row 6.
  4122.                    This is what the OffCenter call would look like:
  4123.  
  4124.                    ' OffCenter example begins
  4125.                    OffCenter "ERROR WARNING", 6, 5, 30
  4126.                    ' OffCenter example ends
  4127.  
  4128.  
  4129.                    Known Limitations: None.
  4130.  
  4131.  
  4132.  
  4133.  
  4134.  
  4135.  
  4136.  
  4137.  
  4138.  
  4139.  
  4140.  
  4141.  
  4142.                                                                page 64
  4143.  
  4144.  
  4145.  
  4146.  
  4147.          Subprogram PUTSCREEN
  4148.          -------------------------------------------------------------
  4149.  
  4150.  
  4151.                    Purpose:  The  PutScreen routine will retrieve from
  4152.                    disk  a  premade  screen   file   (generated   with
  4153.                    GetScreen  or  Screen  Builder) and place it on the
  4154.                    display.  The whole operation  takes  less  than  a
  4155.                    second on a hard disk.
  4156.  
  4157.  
  4158.                    Usage: PutScreen file$
  4159.  
  4160.                              file$ - the disk file that is the  screen
  4161.                                      to be displayed
  4162.  
  4163.  
  4164.                    Details:  This  routine  is  the  mechanism whereby
  4165.                    screens  that  are  generated  via  the   GetScreen
  4166.                    routine or the Screen Builder program are placed on
  4167.                    the screen.  Simply make a call to PutScreen and it
  4168.                    will  load the file from disk and shove it directly
  4169.                    into screen memory.  The  result  is  a  very  fast
  4170.                    display of a premade display.
  4171.  
  4172.                    When you call PutScreen, you send it  the  name  of
  4173.                    the  file  that  stores  the  screen  you  want  to
  4174.                    display.  PutScreen will quickly display it.  Study
  4175.                    the example to see just how easy it is.
  4176.  
  4177.  
  4178.                    Example:  This  example will load a screen that was
  4179.                    previously  generated  using  Screen  Builder,  and
  4180.                    display  it.  The screen was saved in a file called
  4181.                    SCREEN01.CLR.
  4182.  
  4183.                    ' PutScreen example begins
  4184.                    ' Load the screen and display it
  4185.                    PutScreen "SCREEN01.CLR"
  4186.  
  4187.                    ' PutScreen example ends
  4188.  
  4189.  
  4190.                    Known  Limitations:  Works  only  with QBSCR Screen
  4191.                    Builder or GetScreen generated screens.
  4192.  
  4193.  
  4194.  
  4195.  
  4196.  
  4197.  
  4198.  
  4199.  
  4200.  
  4201.  
  4202.  
  4203.  
  4204.                                                                page 65
  4205.  
  4206.  
  4207.  
  4208.  
  4209.          Subprogram QBPRINT
  4210.          -------------------------------------------------------------
  4211.  
  4212.  
  4213.                    Purpose:  Provides  an  combination  of  the print,
  4214.                    locate, and color statements in one  command.   Use
  4215.                    for  the  print  instances  where you need to print
  4216.                    characters that PRINT cannot handle, such as  ASCII
  4217.                    7, the round bullet.
  4218.  
  4219.  
  4220.                    Usage: QBPrint st$, row%, col%, fore%, back%
  4221.  
  4222.                              st$ - the string or string expression  to
  4223.                                    be printed
  4224.                              row% - the row of the  screen  to  locate
  4225.                                    the string
  4226.                              col% - the column of the screen to locate
  4227.                                    the string
  4228.                              fore%  - the foreground color in which to
  4229.                                    display the string
  4230.                              back%  - the background color in which to
  4231.                                    display the string
  4232.  
  4233.  
  4234.                    Details: This routine is most useful when you  need
  4235.                    to either
  4236.  
  4237.                         - Display  a  string  that has a  character(s)
  4238.                           that the QuickBASIC PRINT  statement  cannot
  4239.                           handle, such as ASCII 7 ( CHR$(7) ).  If you
  4240.                           try  to say PRINT CHR$(7) to print the round
  4241.                           bullet ASCII  character,  the  speaker  will
  4242.                           beep instead, since ASCII 7 is also the bell
  4243.                           character.
  4244.  
  4245.                         -  You  want to print something in a different
  4246.                           color  without  having  to  issue  a   COLOR
  4247.                           statement.  This routine will print a string
  4248.                           in  a  different  color without changing the
  4249.                           current COLOR setting.
  4250.  
  4251.                         - You want to print a string without  changing
  4252.                           the  current  cursor position.  This routine
  4253.                           will print at  an  screen  location  without
  4254.                           changing   the   program's   current  cursor
  4255.                           position.
  4256.  
  4257.                    The QBPrint routine can do this because  it  writes
  4258.                    your string directly to the display board's memory.
  4259.                    That's  why  you can print ASCII 7 as a bullet, put
  4260.                    color values into  video  memory  without  changing
  4261.                    BASIC's  color  settings, and locate without moving
  4262.                    the cursor.
  4263.  
  4264.  
  4265.  
  4266.                                                                page 66
  4267.  
  4268.  
  4269.  
  4270.                    QBPrint  supports  all  screen  locations  for  the
  4271.                    LOCATE portion of its capability, foreground colors
  4272.                    from 0 to 31, and background colors from 0 to 7.
  4273.  
  4274.  
  4275.                    Example: This code segment will  display  a  string
  4276.                    expression  on  line  10,  column 25, with a bright
  4277.                    white foreground and  a  blue  background.   It  is
  4278.                    broken onto two lines due to the column width.
  4279.  
  4280.                    ' QBPrint example begins
  4281.                    ' Print a string with characters only QBPrint
  4282.                    ' can handle
  4283.                    QBPrint CHR$(7) + " A bulleted string", 10, 25,
  4284.                                                            15, 1
  4285.  
  4286.                    ' QBPrint example ends
  4287.  
  4288.  
  4289.                    Known Limitations: QBPrint is a little slow when it
  4290.                    comes  to printing an entire screen of information.
  4291.                    Use it sparingly, and only when necessary.  In this
  4292.                    manner, it will be a valuable tool to have around.
  4293.  
  4294.  
  4295.  
  4296.  
  4297.  
  4298.  
  4299.  
  4300.  
  4301.  
  4302.  
  4303.  
  4304.  
  4305.  
  4306.  
  4307.  
  4308.  
  4309.  
  4310.  
  4311.  
  4312.  
  4313.  
  4314.  
  4315.  
  4316.  
  4317.  
  4318.  
  4319.  
  4320.  
  4321.  
  4322.  
  4323.  
  4324.  
  4325.  
  4326.  
  4327.  
  4328.                                                                page 67
  4329.  
  4330.  
  4331.  
  4332.  
  4333.          Function SCREENBLANK
  4334.          -------------------------------------------------------------
  4335.  
  4336.  
  4337.                    Purpose:  Provides  a  screen  saver feature to any
  4338.                    program to prevent image "burn-in."
  4339.  
  4340.  
  4341.                    Usage: x$ = ScreenBlank$(delay)
  4342.  
  4343.                                x$ -  Any  string  variable  that  will
  4344.                                     contain  the  key that was pressed
  4345.                                     during the screen blank.
  4346.                                delay  -   A   numerical   value   that
  4347.                                     represents  the  amount of time to
  4348.                                     wait   between   screen    blanker
  4349.                                     message shifts.
  4350.  
  4351.  
  4352.                    Details:  If  your  application  program leaves the
  4353.                    same image on the screen for any extended period of
  4354.                    time, the image  may  become  "burned  in"  to  the
  4355.                    screen.  The result is a ghost image of the display
  4356.                    forever  left on the monitor.  To prevent this from
  4357.                    happening, you can blank the screen after a defined
  4358.                    period of inactivity.  This will prevent the  image
  4359.                    from  "burning  in".   However,  if  the user later
  4360.                    returns and sees a blank screen, what are  they  to
  4361.                    think?   Anything could be wrong with the computer.
  4362.                    What we need is a small message on  the  screen  to
  4363.                    inform  the  user  that the screen has been blanked
  4364.                    out, and they can hit any  key  to  return  to  the
  4365.                    program.   That  seems  to  solve  the  problem but
  4366.                    there's one twist left: What's to prevent the small
  4367.                    message from itself burning into the  screen?   The
  4368.                    answer  is  surprisingly easy.  We move the message
  4369.                    around on the screen at periodic intervals.  Moving
  4370.                    the message, or "bouncing" it, is easy to  do,  and
  4371.                    the  ScreenBlank  routine  takes  care of all these
  4372.                    features for you.
  4373.  
  4374.                    When  you call ScreenBlank, it is assumed that your
  4375.                    program has determined that a period of  inactivity
  4376.                    of  sufficient  duration  has  elapsed.  The  delay
  4377.                    parameter is a counter.  The larger the value,  the
  4378.                    longer  the  wait  between  the  movements  of  the
  4379.                    ScreenBlank message.  A value of 100,000 is roughly
  4380.                    equal to 3 minutes on a 6 MHz AT-class machine. You
  4381.                    can experiment with the delay to see what suits you
  4382.                    and your machine.
  4383.  
  4384.  
  4385.  
  4386.  
  4387.  
  4388.  
  4389.  
  4390.                                                                page 68
  4391.  
  4392.  
  4393.  
  4394.                    Example:  This example assumes you are checking for
  4395.                    activity in your program.  The code that you  would
  4396.                    execute  if  activity  occurs is only commentary in
  4397.                    this example.  We are representing  the  main  loop
  4398.                    for  any  program here.  The example checks for any
  4399.                    user activity (usually keystrokes).   If  there  is
  4400.                    something  to  do,  it executes any code necessary.
  4401.                    Otherwise, it increments a  counter  we  are  using
  4402.                    called wait.  The wait counter is used to determine
  4403.                    if  the  desired  period of inactivity has elapsed.
  4404.                    If wait ever reaches our preset limit, we  go  into
  4405.                    the  ScreenBlank.   The  key pressed by the user to
  4406.                    exit the ScreenBlank is stored in x$, but since  we
  4407.                    don't need it here we'll just ignore it.
  4408.  
  4409.                    ' ScreenBlank example begins
  4410.                    ' Now sitting in some kind of loop
  4411.                    wait = 0: maxWait = 100000
  4412.                    DO
  4413.                        IF AnyUserActivity THEN
  4414.                            ' Execute any code necessary
  4415.                            wait = 0
  4416.                        ELSE
  4417.                            wait = wait + 1
  4418.                            IF wait > maxWait then
  4419.                                wait = 0
  4420.                                x$ = ScreenBlank$(50000)
  4421.                            END IF   ' wait > maxWait
  4422.                        END IF   ' AnyUserActivity
  4423.                    LOOP UNTIL UserQuits
  4424.                    ' ScreenBlank example ends
  4425.  
  4426.  
  4427.                    Known  Limitations:  The  delay  counter   uses   a
  4428.                    floating  point  value  (single precision real), so
  4429.                    the delay parameter is limited to the maximum value
  4430.                    for single precision reals.
  4431.  
  4432.  
  4433.  
  4434.  
  4435.  
  4436.  
  4437.  
  4438.  
  4439.  
  4440.  
  4441.  
  4442.  
  4443.  
  4444.  
  4445.  
  4446.  
  4447.  
  4448.  
  4449.  
  4450.  
  4451.  
  4452.                                                                page 69
  4453.  
  4454.  
  4455.  
  4456.  
  4457.          Subprogram SCRNRESTORE
  4458.          -------------------------------------------------------------
  4459.  
  4460.  
  4461.                    Purpose: To restore a portion or all of the  screen
  4462.                    saved with the QBSCR SCRNSAVE routine.
  4463.  
  4464.  
  4465.                    Usage: ScrnRestore firstLine%, lastLine%,
  4466.                                       scrArray%(), segment
  4467.  
  4468.                                firstLine%  -  The  first  line  of the
  4469.                                     screen to restore.
  4470.                                lastLine% - The last line of the screen
  4471.                                     to restore.
  4472.                                scrArray%() -  An  integer  array  that
  4473.                                     stores  the information saved from
  4474.                                     the  screen  via  SCRNSAVE.    See
  4475.                                     below for more information.
  4476.                                segment  -  The  beginning  address  of
  4477.                                     video  memory.   Use   the   QBSCR
  4478.                                     routine  GETVIDEOSEGMENT to obtain
  4479.                                     this.  See below for details.
  4480.  
  4481.  
  4482.                    Details: Before you use  the  SCRNRESTORE  routine,
  4483.                    you  have  to  have  something  to  restore  to the
  4484.                    screen.  In the normal course of events  you  would
  4485.                    save  a  portion  or  all  of  the screen using the
  4486.                    SCRNSAVE  routine,  display  something   over   the
  4487.                    existing screen like a window, and then restore the
  4488.                    screen   when   finished   with  the  window  using
  4489.                    SCRNRESTORE.
  4490.  
  4491.                    To use the SCRNRESTORE routine, we can  assume  you
  4492.                    have  saved  a  part  or  all  of the display using
  4493.                    SCRNSAVE.  There  are  points  that   need   to  be
  4494.                    understood before either the SAVE or RESTORE can be
  4495.                    used.   The first is that when you save part of the
  4496.                    screen, the  information  saved  is  stored  in  an
  4497.                    array.   The array must be an integer array, and it
  4498.                    must have 4000  elements.   To  dimension  such  an
  4499.                    array, use the following sort of DIM statement:
  4500.  
  4501.                                    DIM scrArray%(4000)
  4502.  
  4503.                    This  provides  you  an array in which to store the
  4504.                    screen information.  This array is  passed  to  the
  4505.                    SCRNRESTORE  (or SAVE) routine, so that that it has
  4506.                    something to read from (or store to).
  4507.  
  4508.                    The  second  concept  of  importance  is  that  the
  4509.                    SCRNRESTORE (and SAVE) routine know the location of
  4510.                    the beginning of the video card  memory.   This  is
  4511.                    simply a value, and it can easily be obtained using
  4512.  
  4513.  
  4514.                                                                page 70
  4515.  
  4516.  
  4517.                    the  GETVIDEOSEGMENT function in the QBSCR package.
  4518.                    All you have to do is obtain a segment value  using
  4519.                    this function, like this:
  4520.  
  4521.                                 segment = GetVideoSegment
  4522.  
  4523.                    And   then   pass  the  segment  parameter  to  the
  4524.                    SCRNRESTORE (or SAVE) routine, like this:
  4525.  
  4526.                          ScrnRestore 1, 25, scrArray%(), segment
  4527.  
  4528.                    The first and last lines specify the range of lines
  4529.                    on the screen to actually save.  The example  above
  4530.                    would  save the entire screen (lines 1 through 25).
  4531.                    See the example below for usage.
  4532.  
  4533.  
  4534.                    Example: This example uses the SCRNSAVE routine  to
  4535.                    save  a  part  of  the screen.  An error message is
  4536.                    then  displayed  over  the  screen.   Finally,  the
  4537.                    screen  is  restored with SCRNRESTORE when the user
  4538.                    hits a key.
  4539.  
  4540.                    ' ScrnRestore example begins
  4541.                    ' Dimension an array to store the screen contents
  4542.                    DIM scrArray%(4000)
  4543.  
  4544.                    ' Assign first and last line parameters for both
  4545.                    ' SAVE and RESTORE (they are the same).  Saving
  4546.                    ' only the lines that will be overwritten by the
  4547.                    ' error message.
  4548.                    first% = 11
  4549.                    last% = 15
  4550.  
  4551.                    ' Obtain the proper video memory segment
  4552.                    segment = GetVideoSegment
  4553.  
  4554.                    ' Save the designated portion of the screen
  4555.                    ScrnSave first%, last%, scrArray%(), segment
  4556.  
  4557.                    ' Display the error message - this code commented
  4558.                    ' out.  You would display something on the screen
  4559.                    ' on lines 11 through 15.
  4560.  
  4561.                    ' Wait for a keypress.
  4562.                    keyPress$ = INPUT$(1)
  4563.  
  4564.                    ' Restore the screen after the user hits a key.
  4565.                    ScrnRestore first%, last%, scrArray%(), segment
  4566.  
  4567.                    ' ScrnRestore example ends
  4568.  
  4569.                    For more information in the form of  examples,  see
  4570.                    the  source  code  for  the  DEMO  program  or  the
  4571.                    Techniques section of this manual.
  4572.  
  4573.  
  4574.                    Known Limitations: None.
  4575.  
  4576.                                                                page 71
  4577.  
  4578.  
  4579.  
  4580.  
  4581.          Subprogram SCRNSAVE
  4582.          -------------------------------------------------------------
  4583.  
  4584.  
  4585.                    Purpose:  To  save  a  portion or all of the screen
  4586.                    before overwriting it with something else.
  4587.  
  4588.  
  4589.                    Usage: ScrnSave firstLine%, lastLine%,
  4590.                                       scrArray%(), segment
  4591.  
  4592.                                firstLine%  -  The  first  line  of the
  4593.                                     screen to save.
  4594.                                lastLine% - The last line of the screen
  4595.                                     to save.
  4596.                                scrArray%() -  An  integer  array  that
  4597.                                     stores  the information saved from
  4598.                                     the  screen.
  4599.                                segment  -  The  beginning  address  of
  4600.                                     video  memory.   Use   the   QBSCR
  4601.                                     routine  GETVIDEOSEGMENT to obtain
  4602.                                     this.  See below for details.
  4603.  
  4604.  
  4605.                    Details: In the normal course of events  you  would
  4606.                    save  a  portion  or  all  of  the screen using the
  4607.                    SCRNSAVE  routine,  display  something   over   the
  4608.                    existing screen like a window, and then restore the
  4609.                    screen   when   finished   with  the  window  using
  4610.                    SCRNRESTORE.
  4611.  
  4612.                    There are points that need to be understood  before
  4613.                    either  the SAVE or RESTORE can be used.  The first
  4614.                    is that when you  save  part  of  the  screen,  the
  4615.                    information saved is stored in an array.  The array
  4616.                    must  be  an  integer  array, and it must have 4000
  4617.                    elements.  To dimension  such  an  array,  use  the
  4618.                    following sort of DIM statement:
  4619.  
  4620.                                    DIM scrArray%(4000)
  4621.  
  4622.                    This  provides  you  an  array  to store the screen
  4623.                    information.   This  array   is   passed   to   the
  4624.                    SCRNSAVE  (or RESTORE) routine, so that that it has
  4625.                    something in which to save the screen information.
  4626.  
  4627.                    The  second  concept  of  importance  is  that  the
  4628.                    SCRNSAVE (and RESTORE) routine know the location of
  4629.                    the beginning of the video card  memory.   This  is
  4630.                    simply a value, and it can easily be obtained using
  4631.                    the  GETVIDEOSEGMENT function in the QBSCR package.
  4632.                    All you have to do is obtain a segment value  using
  4633.                    this function, like this:
  4634.  
  4635.  
  4636.  
  4637.  
  4638.                                                                page 72
  4639.  
  4640.  
  4641.  
  4642.                                 segment = GetVideoSegment
  4643.  
  4644.                    And   then   pass  the  segment  parameter  to  the
  4645.                    SCRNSAVE (or RESTORE) routine, like this:
  4646.  
  4647.                           ScrnSave 1, 25, scrArray%(), segment
  4648.  
  4649.                    The first and last lines specify the range of lines
  4650.                    on the screen to actually save.  The example  above
  4651.                    would  save the entire screen (lines 1 through 25).
  4652.                    See the example below for usage.
  4653.  
  4654.  
  4655.                    Example:  This example uses the SCRNSAVE routine to
  4656.                    save a part of the screen.   An  error  message  is
  4657.                    then  displayed  over  the  screen.   Finally,  the
  4658.                    screen is restored with SCRNRESTORE when  the  user
  4659.                    hits a key.
  4660.  
  4661.                    ' ScrnSave example begins
  4662.                    ' Dimension an array to store the screen contents
  4663.                    DIM scrArray%(4000)
  4664.  
  4665.                    ' Assign first and last line parameters for both
  4666.                    ' SAVE and RESTORE (they are the same).  Saving
  4667.                    ' only the lines that will be overwritten by the
  4668.                    ' error message.
  4669.                    first% = 11
  4670.                    last% = 15
  4671.  
  4672.                    ' Obtain the proper video memory segment
  4673.                    segment = GetVideoSegment
  4674.  
  4675.                    ' Save the designated portion of the screen
  4676.                    ScrnSave first%, last%, scrArray%(), segment
  4677.  
  4678.                    ' Display the error message - this code commented
  4679.                    ' out.  You would display something on the screen
  4680.                    ' on lines 11 through 15.
  4681.  
  4682.                    ' Wait for a keypress.
  4683.                    keyPress$ = INPUT$(1)
  4684.  
  4685.                    ' Restore the screen after the user hits a key.
  4686.                    ScrnRestore first%, last%, scrArray%(), segment
  4687.  
  4688.                    ' ScrnSave example ends
  4689.  
  4690.                    For  more  information in the form of examples, see
  4691.                    the  source  code  for  the  DEMO  program  or  the
  4692.                    Techniques section of this manual.
  4693.  
  4694.  
  4695.                    Known Limitations: None.
  4696.  
  4697.  
  4698.  
  4699.  
  4700.                                                                page 73
  4701.  
  4702.  
  4703.  
  4704.  
  4705.          Subprogram WIPE
  4706.          -------------------------------------------------------------
  4707.  
  4708.  
  4709.                    Purpose:  To  clear a programmer-defined portion of
  4710.                    the screen.
  4711.  
  4712.  
  4713.                    Usage: Wipe top%, bottom%, lft%, rght%, back%
  4714.  
  4715.                                top% - The top-most row to clear
  4716.                                bottom% - The bottom-most row to clear
  4717.                                lft% - The left-most column to clear
  4718.                                rght% - The right-most column to clear
  4719.                                back  -  The  background  color   with
  4720.                                     which to clear the screen.
  4721.  
  4722.  
  4723.                    Details: The Wipe routine is used to clear selected
  4724.                    portions of the screen.  It is particularly  useful
  4725.                    for  clearing the contents from existing windows so
  4726.                    that they can be reused.
  4727.  
  4728.                    All you need do to use Wipe is to specify the left,
  4729.                    right,  top,  and   bottom   coordinates   of   the
  4730.                    rectangular  area to clear.  Wipe will always clear
  4731.                    the INSIDE of  the  area  you  specify.   In  other
  4732.                    words, if you tell it to clear an area where
  4733.  
  4734.                                         top% = 5
  4735.                                       bottom% = 10
  4736.                                         lft% = 10
  4737.                                        rght% = 70
  4738.  
  4739.                    Wipe would actually clear an area of
  4740.  
  4741.                                         top% = 6
  4742.                                        bottom% = 9
  4743.                                         lft% = 11
  4744.                                        rght% = 69
  4745.  
  4746.                    It  does this so that if you have a window to clear
  4747.                    out, you can call Wipe with the same coordinates as
  4748.                    your window without  erasing  your  screen  border.
  4749.                    Makes using Wipe much easier.
  4750.  
  4751.                    The back% parameter indicates the color to use when
  4752.                    clearing  out  the  defined area, and should be the
  4753.                    same color as the existing background.
  4754.  
  4755.  
  4756.                    Example: The following example will assume we  have
  4757.                    a  window  at  the above listed coordinates, and we
  4758.                    wish to clear it out  for  reuse.   The  background
  4759.                    color of this window is blue.
  4760.  
  4761.  
  4762.                                                                page 74
  4763.  
  4764.  
  4765.  
  4766.                    ' Wipe example begins
  4767.                    ' Set our parameter variables for area to clear
  4768.                    top% = 5
  4769.                    bottom% = 10
  4770.                    lft% = 10
  4771.                    right% = 70
  4772.  
  4773.                    ' Set our background color with which to clear
  4774.                    back% = 1   ' Blue
  4775.  
  4776.                    ' Wipe the area clear
  4777.                    Wipe top%, bottom%, lft%, rght%, back%
  4778.  
  4779.                    ' Wipe example ends
  4780.  
  4781.  
  4782.                    Known Limitations: None.
  4783.  
  4784.  
  4785.  
  4786.  
  4787.  
  4788.  
  4789.  
  4790.  
  4791.  
  4792.  
  4793.  
  4794.  
  4795.  
  4796.  
  4797.  
  4798.  
  4799.  
  4800.  
  4801.  
  4802.  
  4803.  
  4804.  
  4805.  
  4806.  
  4807.  
  4808.  
  4809.  
  4810.  
  4811.  
  4812.  
  4813.  
  4814.  
  4815.  
  4816.  
  4817.  
  4818.  
  4819.  
  4820.  
  4821.  
  4822.  
  4823.  
  4824.                                                                page 75
  4825.  
  4826.  
  4827.  
  4828.  
  4829.          Techniques for Using QBSCR
  4830.          -------------------------------------------------------------
  4831.  
  4832.  
  4833.                    Since  providing  documentation  for  the  routines
  4834.                    won't tell you how to perform specific tasks,  this
  4835.                    manual  has  this section which details some of the
  4836.                    techniques possible with the QBSCR routines.
  4837.  
  4838.                    The  techniques  described  in  here  will not only
  4839.                    clarify the usage of some of the routines, but will
  4840.                    also show  you  how  to  combine  the  routines  to
  4841.                    accomplish  specific  tasks.  These techniques will
  4842.                    add professionalism to any program that yearns  for
  4843.                    it.
  4844.  
  4845.                    Simply choose the section you have interest in, and
  4846.                    the   documentation  will  attempt  to  detail  the
  4847.                    technique in terms of why it is used, what  it  can
  4848.                    do for you, and how to do it.
  4849.  
  4850.  
  4851.  
  4852.  
  4853.  
  4854.  
  4855.  
  4856.  
  4857.  
  4858.  
  4859.  
  4860.  
  4861.  
  4862.  
  4863.  
  4864.  
  4865.  
  4866.  
  4867.  
  4868.  
  4869.  
  4870.  
  4871.  
  4872.  
  4873.  
  4874.  
  4875.  
  4876.  
  4877.  
  4878.  
  4879.  
  4880.  
  4881.  
  4882.  
  4883.  
  4884.  
  4885.  
  4886.                                                                page 76
  4887.  
  4888.  
  4889.  
  4890.  
  4891.          Displaying and Popping a Window from the Screen
  4892.          -------------------------------------------------------------
  4893.  
  4894.  
  4895.                    Many   programs   add   professionalism   to  their
  4896.                    appearance using this technique.  The effect can be
  4897.                    described as laying a window on top of an  existing
  4898.                    display  and when its usefulness has elapsed, it is
  4899.                    "popped," or quickly removed from the  screen,  and
  4900.                    the  underlying display remains intact.  While this
  4901.                    is what appears to happen, the mechanics are a  bit
  4902.                    different.
  4903.  
  4904.                    This is what actually happens:
  4905.  
  4906.                         1) The initial display exists on the screen.
  4907.  
  4908.                         2) The contents  of  the  video  card  memory,
  4909.                            which  contains  the text on the screen and
  4910.                            the color attribute of each  character,  is
  4911.                            saved  inside  the program (in our case, in
  4912.                            an integer array).
  4913.  
  4914.                         3) The new window is is written to the display
  4915.                            overwriting  and  destroying the portion of
  4916.                            the display it now occupies.
  4917.  
  4918.                         4) When the window is to be removed or  popped
  4919.                            from  the  screen, what actually happens is
  4920.                            that the contents of the video memory saved
  4921.                            in  step  2  before  the  new  window   was
  4922.                            displayed  is now restored to video memory.
  4923.                            This causes the old saved information to be
  4924.                            redisplayed.
  4925.  
  4926.                    The window has been effectively displayed and  then
  4927.                    popped  from  the  display  when  it  was no longer
  4928.                    needed.  We can easily perform this task  with  the
  4929.                    QBSCR  Screen Routines.  Specifically, we will need
  4930.                    the  services  of  the  SCRNSAVE,  MAKEWINDOW,  and
  4931.                    SCRNRESTORE   routines.    The   same  step-by-step
  4932.                    process above applies here:
  4933.  
  4934.                         1) Display the initial screen.   This  can  be
  4935.                            displayed   during  the  normal  course  of
  4936.                            program execution.   Any  existing  display
  4937.                            can be saved/restored.
  4938.  
  4939.                         2) Save  the  screen contents into an  integer
  4940.                            array using the SCRNSAVE routine.
  4941.  
  4942.                         3) Place the new window on  the  screen  using
  4943.                            the MAKEWINDOW routine.  You can then print
  4944.                            any text inside the window you need.
  4945.  
  4946.  
  4947.  
  4948.                                                                page 77
  4949.  
  4950.  
  4951.                         4) As  soon  as  you  are  finished  with  the
  4952.                            window, you can restore the original screen
  4953.                            contents, thus popping the window  off  the
  4954.                            display, using the SCRNRESTORE routine.
  4955.  
  4956.                    The  use  of  windows  is  extremely   useful   for
  4957.                    isolating  a single thought, concept or activity on
  4958.                    your display screen.   Using  this  technique  will
  4959.                    allow  you  to  use  windows  while  retaining  the
  4960.                    integrity of  the  underlying  screen.   This  will
  4961.                    result  in  much  faster execution time and happier
  4962.                    users, since you and they don't  have  to  wait  to
  4963.                    redraw the whole screen.
  4964.  
  4965.                    We'll  now  go  through  a practical example of the
  4966.                    entire process.  To use  an  earlier  example,  our
  4967.                    task  is  to display an error message in the middle
  4968.                    whatever screen currently exists  on  the  display.
  4969.                    Who  knows  when  an  error  will come up?  We will
  4970.                    assume that  there  is  some  sort  of  event  that
  4971.                    triggers  the  error  -  we're  only going to worry
  4972.                    about displaying the error in  a  window  and  then
  4973.                    restoring the display.  Other assumptions are:
  4974.  
  4975.                         1) The error message will never be more than 5
  4976.                            lines  long,  each  of  which  will  be  60
  4977.                            characters  or  less in length.  This means
  4978.                            we will need 7 display lines  (5  lines  of
  4979.                            error text + 2 lines for the window frame).
  4980.  
  4981.                         2) The user will hit a key to clear the  error
  4982.                            message window from the screen,  signifying
  4983.                            that they are finished reading it.
  4984.  
  4985.                         3) The software will be  running  on  a  color
  4986.                            display.
  4987.  
  4988.                         4) There will be a routine called ErrorMessage
  4989.                            that  will  place  the appropriate text for
  4990.                            the error message inside our window.
  4991.  
  4992.                    So  let's begin our example.  The code here will be
  4993.                    commented  well  so  that  it   is   clear   what's
  4994.                    happening.
  4995.  
  4996.                    ' Window display/removal example begins
  4997.                    ' Dimension an array to store screen contents
  4998.                    DIM scrArray%(4000)
  4999.  
  5000.                    ' Save the portion of the screen we will be
  5001.                    ' overwriting.  Our window will  always  be
  5002.                    ' located between rows 10 and 16.  First
  5003.                    ' though, we need the proper video segment.
  5004.                    segment = GetVideoSegment
  5005.  
  5006.                    ' Now we can save the portion of the screen we will
  5007.                    ' be overwriting.
  5008.                    ScrnSave 10, 16, scrArray%(), segment
  5009.  
  5010.                                                                page 78
  5011.  
  5012.  
  5013.  
  5014.                    ' We've now paid our insurance - lets display the
  5015.                    ' error message window.  We will assign our window
  5016.                    ' parameters as variables for readability.
  5017.                    leftCol = 8: rightCol = 73
  5018.                    topRow = 10: botRow = 16
  5019.                    foreColor% = 15    ' Bright White
  5020.                    backColor% = 4     ' Red
  5021.                    windowType% = 0    ' Normal window, no inside lines
  5022.                    frameType% = 1     ' All double lines
  5023.                    shadowColor% = 0   ' Black window shadow
  5024.                    explodeType% = 1   ' Automatic explode mode
  5025.                    label$ = " Error! "
  5026.  
  5027.                    ' Make the window on the screen.  Note that in your
  5028.                    ' real program this next statement would be on a
  5029.                    ' single line.
  5030.                    MakeWindow topRow, leftCol, BotRow, rightCol,
  5031.                               foreColor%, backColor%, windowType%,
  5032.                               frameType%, shadowColor%, explodeType%,
  5033.                               label$
  5034.  
  5035.                    ' Add the error text to the window.  We will assume
  5036.                    ' that there is a routine called ErrorMessage  that
  5037.                    ' will place the correct message at the right  spot
  5038.                    ' on the screen.
  5039.                    ErrorMessage
  5040.  
  5041.                    ' Wait for the user to hit a key,  signifying  that
  5042.                    ' they are finished with the message.
  5043.                    keyPress$ = INPUT$(1)
  5044.  
  5045.                    ' Now  that  the user is done, we will restore  the
  5046.                    ' screen to the state it was in  before  the  error
  5047.                    ' message window was displayed using SCRNRESTORE.
  5048.                    ScrnRestore 10, 16, scrArray%(), segment
  5049.  
  5050.                    ' Window display/removal example ends
  5051.  
  5052.                    Note  that  you  should  only  save and restore the
  5053.                    smallest amount of the screen as you need to. Doing
  5054.                    so will result in much faster performance.
  5055.  
  5056.                    This  technique  can  be  used for multiple windows
  5057.                    simultaneously by having an integer array for  each
  5058.                    window  you  place  on the screen.  Save the screen
  5059.                    with a new array each time you add a new window  to
  5060.                    the screen.  In this way, you can reverse the order
  5061.                    when  you  restore screens, and the windows will be
  5062.                    removed from the display one at a time in order.
  5063.  
  5064.  
  5065.  
  5066.  
  5067.  
  5068.  
  5069.  
  5070.  
  5071.  
  5072.                                                                page 79
  5073.  
  5074.  
  5075.  
  5076.  
  5077.          Visual Effects with BUILDSCREEN and CLRSCR
  5078.          -------------------------------------------------------------
  5079.  
  5080.  
  5081.                    BuildScreen and ClrScr are complimentary  routines.
  5082.                    Although one creates screens and the other destroys
  5083.                    them, they perform these tasks in the same way.  If
  5084.                    you  look  at  the  source  code  for each routine,
  5085.                    you'll  see  that  they  are  very  similar.   Each
  5086.                    routine  also  supports  exactly  the same modes of
  5087.                    animation.  ClrScr mode 10, for example, will clear
  5088.                    the screen in a spiral fashion,  while  BuildScreen
  5089.                    mode  10  displays  a  screen  in  the  same spiral
  5090.                    fashion.
  5091.  
  5092.                    Since the modes of animation are the same for  each
  5093.                    routine,  they  can  be  used  together  to  create
  5094.                    interesting visual effects.  A perfect  example  is
  5095.                    demonstrated  in  the  DEMO  program.  This example
  5096.                    uses complimentary ClrScr and BuildScreen routines.
  5097.                    ClrScr is used to  first  clear  the  screen  using
  5098.                    ASCII   character   176  (░)  with  mode  3,  which
  5099.                    resembles curtains closing on  a  stage.   Then the
  5100.                    display  is  placed on the screen using BuildScreen
  5101.                    mode 2, which is the complimentary opposite mode of
  5102.                    mode 3 just used with  ClrScr.   The  effect  looks
  5103.                    likes curtains closing on the existing display, and
  5104.                    the curtains open again revealing the new display.
  5105.  
  5106.                    Techniques  like  this  can be generated easily for
  5107.                    opening screens of programs or other displays.  For
  5108.                    details on the example  described  above,  see  the
  5109.                    source code for the DEMO program.  Other modes that
  5110.                    match  well  can be used to create similar effects.
  5111.                    Use the REF program  to  see  all  the  ClrScr  and
  5112.                    BuildScreen  modes.   By  playing around a bit, you
  5113.                    may discover an impressive way  to  open  your  own
  5114.                    program.
  5115.  
  5116.  
  5117.  
  5118.  
  5119.  
  5120.  
  5121.  
  5122.  
  5123.  
  5124.  
  5125.  
  5126.  
  5127.  
  5128.  
  5129.  
  5130.  
  5131.  
  5132.  
  5133.  
  5134.                                                                page 80
  5135.  
  5136.  
  5137.  
  5138.  
  5139.          Window Making Techniques
  5140.          -------------------------------------------------------------
  5141.  
  5142.  
  5143.                    Creating a "Frameless" Window
  5144.                    ---------------------------------------------------
  5145.                    Sometimes you don't want a border, or frame, around
  5146.                    your  window.   You just want a colored field.  You
  5147.                    can do this two ways.
  5148.  
  5149.                    The  first  and  most  obvious method is to use the
  5150.                    MakeWindow routine.  You  can  do  this  easily  by
  5151.                    making   the   foreground   and   background  color
  5152.                    parameters the same value.   If  for  instance  you
  5153.                    wanted  to make a red frameless window, simply make
  5154.                    the foreColor and backColor parameters the same, in
  5155.                    our case, 4.  It doesn't matter what the  frameType
  5156.                    or  windowType  parameters  are since you won't see
  5157.                    them.  Choose any valid value such as zero for both
  5158.                    parameters.
  5159.  
  5160.                    The drawback with this technique is that  you  must
  5161.                    provide  all the MakeWindow parameters.  There is a
  5162.                    shortcut for creating a frameless window.   You  do
  5163.                    so by using the Wipe routine.  Simply pass Wipe the
  5164.                    coordinates  for  your  window  and a color for the
  5165.                    field.  This results in the much easier creation of
  5166.                    a frameless window.
  5167.  
  5168.                    Of course, if you want a shadow for the window,  or
  5169.                    you  want  it to explode onto the screen, the first
  5170.                    option is your best bet.  Frameless windows, by the
  5171.                    way, look great with a black shadow.
  5172.  
  5173.  
  5174.                    Window Shadows
  5175.                    ---------------------------------------------------
  5176.                    And speaking of window shadows, the new shadow mode
  5177.                    that  MakeWindow  incorporates  will add a definite
  5178.                    touch of professionalism to any program  that  uses
  5179.                    windows.
  5180.  
  5181.                    The  new shadow type is 16, and will leave existing
  5182.                    characters in the shadowed region  on  the  screen.
  5183.                    It   will,   however,   change  the  color  of  the
  5184.                    characters so they are in plain  white  (color  7).
  5185.                    This   is  exactly  the  same  shadowing  that  the
  5186.                    QuickBASIC environment uses, and looks very  sharp.
  5187.                    If  you  plan  to  be  using  color  displays, then
  5188.                    seriously consider this shadow mode.
  5189.  
  5190.  
  5191.  
  5192.  
  5193.  
  5194.  
  5195.  
  5196.                                                                page 81
  5197.  
  5198.  
  5199.  
  5200.  
  5201.          Menu Techniques
  5202.          -------------------------------------------------------------
  5203.  
  5204.  
  5205.                    Producing a Clear and Clean Menu
  5206.                    ---------------------------------------------------
  5207.                    When  generating  menus  for  a person to use, it's
  5208.                    important to keep a couple of  design  concepts  in
  5209.                    mind.
  5210.  
  5211.                    Your  menus  should  be easy to use and understand.
  5212.                    This means keeping the  menu  focused  without  too
  5213.                    many  choices.   Users  tend to work best when they
  5214.                    have nine or fewer choices to decide between.   The
  5215.                    choices  themselves should be concise yet distinct.
  5216.                    There  shouldn't  be  any  question  about  what  a
  5217.                    particular  entry  does.   You can accomplish these
  5218.                    goals by giving your entries careful thought.  Make
  5219.                    sure each is meaningful, and keep your menu choices
  5220.                    to as few as possible.
  5221.  
  5222.                    There are specific things you can do with the QBSCR
  5223.                    MakeMenu function to further these aims.
  5224.  
  5225.                         1) Keep your menu entries  to  a  minimum  and
  5226.                            make sure they are clear.
  5227.  
  5228.                         2) Use "Quick Access" keys to make your  menus
  5229.                            easier   to   use.   By  providing  both  a
  5230.                            selection bar and Quick  Access  keys,  you
  5231.                            satisfy  the  needs  of both the novice and
  5232.                            the advanced user.
  5233.  
  5234.                         3) Choose your Quick  Access  Keys  carefully.
  5235.                            Specifically,  choose ones that are easy to
  5236.                            remember.  For instance, if your  entry  is
  5237.                            "Save File,"  the S would make an excellent
  5238.                            Quick   Access  key,  since  S  is  closely
  5239.                            related to  the  primary  function  of  the
  5240.                            entry,  Saving  a  file.  The V wouldn't be
  5241.                            terrible, but the F  would  be  the  worst,
  5242.                            since  you  might also have "Edit File" and
  5243.                            "Load  File"  entries.   The  F  would  not
  5244.                            distinguish  the  Save function from any of
  5245.                            the other file operations.
  5246.  
  5247.                         4) Always provide  on-screen  instructions  on
  5248.                            how to use the menu.
  5249.  
  5250.  
  5251.  
  5252.  
  5253.  
  5254.  
  5255.  
  5256.  
  5257.  
  5258.                                                                page 82
  5259.  
  5260.  
  5261.  
  5262.                         5) Keep your menus clean.  Isolate  them  from
  5263.                            any  other  distracting screen information.
  5264.                            You can do this by
  5265.  
  5266.                                 a) choosing a location on  the  screen
  5267.                                    that is as removed as possible from
  5268.                                    other  information  on  the screen,
  5269.                                    and
  5270.  
  5271.                                 b) placing your menu inside a window.
  5272.  
  5273.                            If you place your menu inside a window,  it
  5274.                            isolates  the  menu  even  further from the
  5275.                            rest of the world.  This will help the user
  5276.                            focus on the menu and the  decision  to  be
  5277.                            made there.
  5278.  
  5279.                    While  all these ideas may sound odd or picky, they
  5280.                    all  come  together  to  make   your   menus   more
  5281.                    presentable,  easy  to  use,  and professional. The
  5282.                    user may not be thinking "Wow, this menu is  nicely
  5283.                    isolated  and  that  makes it easier for me to deal
  5284.                    with," but it inherently will  be.   Their  overall
  5285.                    impression  will  be  more  favorable, even if they
  5286.                    don't  specifically know why.  They should at least
  5287.                    get  the  impression  that  the  program  is   well
  5288.                    organized.
  5289.  
  5290.  
  5291.  
  5292.  
  5293.  
  5294.  
  5295.  
  5296.  
  5297.  
  5298.  
  5299.  
  5300.  
  5301.  
  5302.  
  5303.  
  5304.  
  5305.  
  5306.  
  5307.  
  5308.  
  5309.  
  5310.  
  5311.  
  5312.  
  5313.  
  5314.  
  5315.  
  5316.  
  5317.  
  5318.  
  5319.  
  5320.                                                                page 83
  5321.  
  5322.  
  5323.  
  5324.  
  5325.          Cross Reference - Routine Dependencies
  5326.          -------------------------------------------------------------
  5327.  
  5328.  
  5329.                    To make code more  efficient,  some  of  the  QBSCR
  5330.                    routines  make  use of each other's services.  This
  5331.                    section of the documentation  will  detail  exactly
  5332.                    what routines are dependent on others, and on which
  5333.                    ones.   Consult this table carefully if you plan to
  5334.                    be pruning off  routines  your  particular  program
  5335.                    will not be using.
  5336.  
  5337.                    Also  note that there are two routines in the QBSCR
  5338.                    package that are not documented except here.   They
  5339.                    are   the   function  SubMenu  and  the  subprogram
  5340.                    DisplayEntry.  They are  used  only  internally  by
  5341.                    other routines, which are detailed below.
  5342.  
  5343.                    Routine...                       ...is dependent on
  5344.                    ---------------------------------------------------
  5345.                    Banner . . . . . . . . . . . . . . . . . . . . none
  5346.                    BlockRestore . . . . . . . . . . . . . . . . . none
  5347.                    BlockSave  . . . . . . . . . . . . . . . . . . none
  5348.                    BlockSize  . . . . . . . . . . . . . . . . . . none
  5349.                    BuildScreen  . . . . . . . . . . .  GetVideoSegment
  5350.                    Center . . . . . . . . . . . . . . . . . . . . none
  5351.                    ClrScr . . . . . . . . . . . . . . . . . . . . none
  5352.                    ColorChk . . . . . . . . . . . . . . . . . . . none
  5353.                    DisplayEntry . . . . . . . . . . . . . . . . . none
  5354.                    GetBackground  . . . . . . . . . .  GetVideoSegment
  5355.                    GetForeground  . . . . . . . . . .  GetVideoSegment
  5356.                    GetScreen  . . . . . . . . . . . .  GetVideoSegment
  5357.                    GetString  . . . . . . . . . . . . . . . . . . none
  5358.                    GetVideoSegment  . . . . . . . . . . . . . . . none
  5359.                    MakeMenu . . . . . . . . . . . . . . . DisplayEntry
  5360.                    MakeWindow . . . . . . . . . . . .  GetVideoSegment
  5361.                    MultiMenu  . . . . . . . . . . . . . . BlockRestore
  5362.                                                              BlockSave
  5363.                                                           DisplayEntry
  5364.                                                        GetVideoSegment
  5365.                                                             MakeWindow
  5366.                                                                SubMenu
  5367.                    OffCenter  . . . . . . . . . . . . . . . . . . none
  5368.                    PutScreen  . . . . . . . . . . . .  GetVideoSegment
  5369.                    QBPrint  . . . . . . . . . . . . .  GetVideoSegment
  5370.                    ScreenBlank  . . . . . . . . . . . . . . . . . none
  5371.                    ScrnRestore  . . . . . . . . . . . . . . . . . none
  5372.                    ScrnSave . . . . . . . . . . . . . . . . . . . none
  5373.                    SubMenu  . . . . . . . . . . . . . . . DisplayEntry
  5374.                    Wipe . . . . . . . . . . . . . . . . . . . . . none
  5375.  
  5376.  
  5377.  
  5378.  
  5379.  
  5380.  
  5381.  
  5382.                                                                page 84
  5383.  
  5384.  
  5385.  
  5386.  
  5387.          Closing Notes
  5388.          -------------------------------------------------------------
  5389.  
  5390.  
  5391.                    I sincerely hope that the QBSCR Screen Routines are
  5392.                    of some help to you, either in a productivity or  a
  5393.                    tutorial  capacity.   The Screen Routines try their
  5394.                    best to fill both roles.
  5395.  
  5396.                    The BAD SOFTWARE Company has two  missions  in  the
  5397.                    world  of  software for the IBM PC and compatibles.
  5398.                    The first is to provide useful software that's easy
  5399.                    to use.  The primary purpose  of  any  software  is
  5400.                    that it does something you want or need. Therefore,
  5401.                    BAD  SOFTWARE  is  dedicated  to the development of
  5402.                    software that has these qualities.  But the  second
  5403.                    item of importance to BAD SOFTWARE is that software
  5404.                    be  fun.   Computing  need not be a chore to avoid.
  5405.                    The QBSCR Screen Routines  hopefully  fulfill  this
  5406.                    requirement.   It's  always been fun for me to make
  5407.                    my own programs appear as professional as possible,
  5408.                    and the  Screen  Routines  let  me  do  this  while
  5409.                    expending  very little time and effort.  I can only
  5410.                    hope that they will do the same for you.
  5411.  
  5412.                    If you have any comments or ideas about the  Screen
  5413.                    Routines,  please  feel free to drop me a letter at
  5414.                    the following address.  I'll do my best  to  answer
  5415.                    all correspondence.
  5416.  
  5417.                                        Tony Martin
  5418.                                  1611 Harvest Green Ct.
  5419.                                     Reston, VA 22094
  5420.  
  5421.                    Lastly,   I  must  acknowledge  a  few  copyrights.
  5422.                    Microsoft  and   QuickBASIC   are   trademarks   of
  5423.                    Microsoft  Corporation.   I'm  sure you didn't know
  5424.                    this...
  5425.  
  5426.  
  5427.  
  5428.  
  5429.  
  5430.  
  5431.  
  5432.  
  5433.  
  5434.  
  5435.  
  5436.  
  5437.  
  5438.  
  5439.  
  5440.  
  5441.  
  5442.  
  5443.  
  5444.                                                                page 85
  5445.  
  5446.  
  5447.  
  5448.  
  5449.          Registration Form
  5450.          -------------------------------------------------------------
  5451.  
  5452.  
  5453.                    If  you  decide  to  register  the   QBSCR   Screen
  5454.                    Routines,  send a check for $15.00 U.S. made out to
  5455.                    Tony Martin to:
  5456.  
  5457.                                        Tony Martin
  5458.                                  1611 Harvest Green Ct.
  5459.                                     Reston, VA 22094
  5460.  
  5461.                    In  return  I  will  send  you an official disk set
  5462.                    containing all the files of the latest  version  of
  5463.                    the  Screen Routines.  In addition you will receive
  5464.                    a free copy of  the  LASER  graphics  entertainment
  5465.                    program  written  by  BAD SOFTWARE exclusively  for
  5466.                    registered users of BAD SOFTWARE products.
  5467.  
  5468.                    ---------------------------------------------------
  5469.  
  5470.                    Complete this registration form and send with  your
  5471.                    check to the above listed address.
  5472.  
  5473.                    Product: QBSCR Screen Routines
  5474.  
  5475.                    Version: 1.5
  5476.  
  5477.                    Cost $15.00
  5478.  
  5479.                    Quantity: ________
  5480.  
  5481.                    Total: $__________
  5482.  
  5483.                    Ship to:
  5484.  
  5485.                    Name:______________________________________________
  5486.  
  5487.                    Address: __________________________________________
  5488.  
  5489.                    City/State/Zip: ___________________________________
  5490.  
  5491.  
  5492.  
  5493.  
  5494.  
  5495.  
  5496.  
  5497.  
  5498.  
  5499.  
  5500.  
  5501.  
  5502.  
  5503.  
  5504.  
  5505.  
  5506.                                                                page 86
  5507.  
  5508.  
  5509.